In my thinking, clojure vectors have a slight performance hit compared to java arrays. As a result I thought that \"conventional wisdom\" was that for those performance-crit
it looks like reflection is washing out all your test's accuracy:
user> (set! *warn-on-reflection* true)
true
user> (def x (vec (range 100000)))
#'user/x
user> (def xa (int-array x))
#'user/xa
user> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ s (nth x i))) s)))
NO_SOURCE_FILE:1 recur arg for primitive local: s is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: s
"Elapsed time: 12.11893 msecs"
4999950000
user> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ s (aget xa i))) s)))
Reflection warning, NO_SOURCE_FILE:1 - call to aget can't be resolved.
NO_SOURCE_FILE:1 recur arg for primitive local: s is not matching primitive, had: Object, needed: long
Auto-boxing loop arg: s
Reflection warning, NO_SOURCE_FILE:1 - call to aget can't be resolved.
"Elapsed time: 2689.865468 msecs"
4999950000
user>
the second one just happens to have more reflection in it.
When running this kind of benchmark be sure to run it many times to get the hotSpot compiler warmed up
user> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ s (aget xa i))) (long s))))
"Elapsed time: 3135.651399 msecs"
4999950000
user> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ (long s) (aget xa i))) (long s))))
"Elapsed time: 1014.218461 msecs"
4999950000
user> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ (long s) (aget xa i))) (long s))))
"Elapsed time: 998.280869 msecs"
4999950000
user> (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ (long s) (aget xa i))) (long s))))
"Elapsed time: 970.17736 msecs"
4999950000
in this case a few runs dropped it down to 1/3 the original time (though reflection is still the main problem here)
if I warm them both up with dotimes the results improve a lot:
(dotimes [_ 1000] (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ s (nth x i))) s))))
"Elapsed time: 3.704714 msecs"
(dotimes [_ 1000] (time (loop [i 0 s 0] (if (< i 100000) (recur (inc i) (+ (long s) (aget xa i))) (long s)))))
"Elapsed time: 936.03987 msecs"