Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optimizing array mutation in Clojure

Having read a few blog posts on the subject, I have found that mutating an array in Clojure like this:

(defn m [xs ys] 
  (dotimes [i (count xs)] 
    (aset #^ints ys (int i) 
    (int (* (int 3) (int (aget #^ints xs (int i))))))))

where (def xs (into-array Integer/TYPE (range 1000000))) and (def ys (into-array Integer/TYPE (range 1000000)))

took an average of 14ms according to Criterium, whereas the Java to do the same,

public static int[] m(int[] x, int[] y)
{
  for(int i=0; i<x.length; i++)
    y[i] = 3*x[i];
  return y;
}

takes an average of 800us. **

Am I doing all I can to makes things go fast and Is there any further I can go down the optimization path ?

** I timed these using Criterium with (report-result (bench (m xs ys )) :verbose) and (report-result (bench (. Test m xs ys)) :verbose)

like image 597
Hendekagon Avatar asked Apr 16 '12 06:04

Hendekagon


1 Answers

Try this on Clojure 1.3:

(set! *unchecked-math* true)

(defn m [^longs xs ^longs ys]
  (dotimes [i (count xs)]
    (aset ys i
      (* 3 (aget xs i)))))
like image 52
dnolen Avatar answered Sep 28 '22 02:09

dnolen