Dear all,

The good news: I have a version of the N-body benchmark that goes "as
fast as java".

The bad news: I am cheating a little bit...

As I suspected that a lot of time was spend in the array bound check
arithmetic, I replaced #^doubles in the implementation of body by an
object implemented in Java. (That's where I cheated).
I just created a Body struct with 7 public double fields.

This resulted in a x 2.3 speed-up from the last version.

Then replacing persistent vectors for bodies by Java array gives another
15% speed increase.

Then using my own Java written function to have a more specific
signature to array access gave another 15%. (This means that type cast
seems to have a cost in a very tight loop)

Starting with a program running in 66 sec, I have now a program running
in 17 sec (for 5. 10^7 iterations)
I have not ran the java program but as the 66 sec one was 3.2 times
slower than the Java one, I think the goal is reached.

But we had to cheat.
I think the most crucial point is that there is no way in Clojure to
implement structures with the same performance characteristics than
native java structures. (In this kind of loop, it speed up by 2-2.5
times the program to use such a java object.)

I think I read an article about an array bound check elimination for
jre7 that would get read of a big part of the cost. But having to encode
structures as arrays to have primitive fields is not very idiomatic
anyway.

So to sum up how to have micro-benchmarks as fast as java:
- manual inlining. There seems to have a cost to calling a function.
Maybe the new code generator will improve that. 
- possibility to have "native structures". As for now that means writing
small java files. Maybe the new new will improve that. I also read
someone has a gen-struct macro. (biggest factor)
- the right set of options for the JVM. (Escape analysis, biased
locking, AggressiveOpts)
- possibility of having array access similar to those for primitives for
any type. (Less important than the other.)

I think it may be reassuring for people starting a project using Clojure
to know that once they find a bottleneck in a program they can rewrite
it to go at the same speed as the java program doing the same thing.

That's not a programming style I would advocate for a whole project
though. 

Best regards,

Nicolas.
 

On Wed, 2009-08-12 at 00:26 -0400, Aaron Cohen wrote: 
> On Tue, Aug 11, 2009 at 8:13 PM, Andy
> Fingerhut<andy_finger...@alum.wustl.edu> wrote:
> >
> > On Aug 11, 2:36 pm, Aaron Cohen <remled...@gmail.com> wrote:
> >> At that point is it possible you're just paying the price of
> >> PersistentVector for the "bodies" vector?  Does it improve much if you
> >> change bodies to an array?
> >
> > About 7% faster changing bodies to a Java array of java.lang.Object's,
> > each of which happens to be a Java array of primitive doubles, as
> > before.  Now about 3.0 x Java run time.
> >
> > http://github.com/jafingerhut/clojure-benchmarks/blob/43ed2f42e6c1485541532e51eacc66488949c658/RESULTS
> >
> 
> I'm actually glad that the difference is that small there.
> 
> > 


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