Optimizing array mutation in Clojure

arrays, clojure, optimization

Solution

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)))))

Problem

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)`

Original source