So out of curiosity I did some benchmarking of the new equal branch and wanted to see how much I can get out of clojure if I push the limits. Now that said I know equal isn't done yet but I figured it won't hurt. Bad news first, despite all my attempts clojure was still slower then optimized scala code (of cause this is a purely hypothetical benchmark and that scala is way closer to java gives it a huge advantage when it coms to that).
The benchmark I did was the fannkuchen-redux benchmark the code I came up with was the following: http://github.com/Licenser/clj-shootout/blob/master/fannkuchen/src/profile/fannkuchen.clj the scala version I used is from the alioth shootout: http://github.com/Licenser/clj-shootout/blob/master/fannkuchen/scala/fannkuchen.scala For the clojure version, I tried to get rid of anything that isn't very close to java. All data ist stored in mutable arrays, all in all I use three and no extra data is allocated or tossed away for this. I tried to make everything I could to a macro (removing overhead for function calls), also I tried to use unchecked and primitive math wherever possible. The code is not pretty and certainly not idiomatic but it is somewhat fast, I managed to get things to a point where my clojure version took only 3.5 times longer then the scala version (I say only since the most idiomatic version was beyond compare so it was just beautiful!). After this I did some profiling - eevar will love me for that - and I noticed one thing that stood out. intCast is called a gazillion times (in a run of about 4 seconds it was called ca. 150 million times) that IS a lot and it took some time (more then 10% of the over all execution time). That stroke me as odd, so I did some diging and found an interesting point: Java arrays use int's as index - which since long is the primitive causes every single array access to be typecast via the intCast(long) call which is expensive since it does range checking. Now since clojure is open source - yay - I changed the aget java code to take a long and do a unckeded typecast as in '(int)i' when accessing the array and made my own aget and aset methods that did not typecheck (since I knew what it was called with). This bought about 10% execution time. So what I'd suggest is to add some unckecked-aget methods that take a long as index and don't typecast, for array intensive code this is a 10% speedup which isn't that bad. Other then that I am still looking why clojure is slower by such a magnitude. Also it would be great if there were a way to give functions signatures if desired, as in having (aget Object) that runs (int ...) on Object and (aget int/long) that does just pass the value w/o casting. Also the profiles show that despite my best efforts there is still a large number of calls made for Number casts, I'm not sure where they are from, likely from clojures core interiors. Here are some of the results I got: http://grab.by/57x0 and some profiling results: http://grab.by/57vO (look at the time taken for intCast) Regards, Heinz -- 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