Using `def` like that is simply incorrect. `def` should always be at the top level unlike say Scheme.
I would first remove all internal defs and then rerun your benchmarks. On Fri, Jun 21, 2013 at 8:36 AM, Colin Yates <colin.ya...@gmail.com> wrote: > Hi all, > > I am doing some (naive and trivial) performance tests before deciding > whether and how to use Clojure for some performance critical number > cruching and I wanted help understanding the behaviour. > > I am defining an array inside a function, setting the contents to be 1 and > then summing them up (by areducing) them (I chose 1 instead of a random > number for consistency, obviously the contents will be different otherwise > it would all reduce to (n) :)). If I 'let' the array then it is factors of > 10 faster than if I def the array. > > The relevant code ( > https://github.com/yatesco/clojure-perf/blob/master/src/inc.clj): > > [code] > (ns inc > (:gen-class)) > > (defn- inc-atom [n] > (def x (atom 0)) > (dotimes [n n] (swap! x inc)) > @x) > > (defn- array-let [n] > (let [a (int-array n)] > (dotimes [n n] (aset-int a n 1)) > (areduce a i ret 0 > (+ ret (aget a i))))) > > (defn- array-def [n] > (def a (int-array n)) > (dotimes [n n] (aset-int a n 1)) > (areduce a i ret 0 > (+ ret (aget a i)))) > > (defn- run-test [subject n] > (time (do (def x (subject n)) (println x)))) > > (defn -main [& args] > (let [n 1000000] > (println "inc atom") > (run-test inc-atom n) > (println "array with let") > (run-test array-let n) > (println "array with def") > (run-test array-def n)) > ) > [/code] > > Interestingly, if I refactored an 'execute-on-array' def which array-let > and array-def delegated to then they had the same performance which seems > to imply it is about scoping, but the array in both array-let and array-def > have exactly the same scope... Setting the autoboxing warning to true > didn't point out anything either. > > The output (from my VM, so a bit slow): > [code] > inc atom > 1000000 > "Elapsed time: 213.214118 msecs" > array with let > 1000000 > "Elapsed time: 75.302602 msecs" > array with def > 1000000 > "Elapsed time: 12868.970203 msecs" > [/code] > > For comparison, the following java code: > > [code] > package perf; > > public class Inc { > public static void main(String[] args) { > int n = 1000000; > int counter = 0; > long start = System.currentTimeMillis(); > for (int i=0; i<n; i++) counter++; > long end = System.currentTimeMillis(); > System.out.println ("Naive " + (end - start) + " ms, counter is " > + counter); > > counter = 0; > int[] arr = new int[n]; > start = System.currentTimeMillis(); > for (int i=0; i<arr.length; i++) arr[i]=1; > for (int i=0; i<arr.length; i++) counter = counter + arr[i]; > end = System.currentTimeMillis(); > System.out.println ("Array " + (end - start) + " ms, counter is " > + counter); > } > } > [/code] > > produces the (as expected, much faster) results : > > [code] > Naive 3 ms, counter is 1000000 > Array 6 ms, counter is 1000000 > [/code] > > I am not surprised that the atom/inc takes much longer than 3 ms, but I > don't understand why the array solution is so much more expensive in > Clojure? > > On a related point - can anyone provide a faster implementation of summing > up the contents of an array? > > A lein project can be found https://github.com/yatesco/clojure-perf, > 'lein uberjar; java -jar target/*.jar should demonstrate the output. > > -- > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/groups/opt_out. > > > -- -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.