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

Reply via email to