On Feb 12, 2009, at 5:35 PM, Dimiter malkia Stanev wrote:
> > Hi guys, > > I'm optimizing a little benchmark called pnpoly, and I was wondering > what is the proper way of hinting the compiler for types. In certain > cases Clojure accepts for example loop [#^Integer c 0] and in others > loop [c (int 0)] - I'm really trying to hint the compiler as best as I > can. > > I'm synced to the latest SVN version (1162), and in the same source > code, it seems like loop[#^Integer c 0] works for some cases, and not > for others. > > Here is the code in question: > > http://paste.lisp.org/display/75370 > > Also please note, what I'm doing wrong in it, what could be achieved > more. My next step is to parallelize it, and compare again. > > So on my machine Clojure gives this result: (-600000 is okay, I was > testing which one is better bit-not or subtracting 1 from the number). > ; SLIME 2009-02-07 > user> (time (pnpoly/pnpolytest)) > "Elapsed time: 16075.309949 msecs" > -6000000 > > C version is about 0.8s, Lispworks 1.3s, other Common Lisps (SBCL, > CMUCL) about 2.0s ABCL: 6sec (using Java 1.6_10 -server, much like > what I'm using for clojure). > > 16seconds it's not really that bad, considering I won't be using > Clojure for heavy math code, but still wanted to see what I can do > more with it. > > For example the same example in Python, Ruby or Perl runs at least for > 200s (same with CLISP, haven't tried ECL or GCL). > Try this: http://paste.lisp.org/display/75370#3 A few things to note: - All arguments are passed to Clojure fns as objects, so there's no point to putting non-array primitive type hints on fn args. Instead, use the let technique shown to place args in primitive locals if they need to participate in primitive arithmetic in the body. - (let [foo (int bar)] ...) is the correct way to get a primitive local. Do not use #^Integer etc. - Don't rush to unchecked math unless you want truncating operations. HotSpot does a good job at optimizing the overflow check, which will yield an exception instead of silent truncation. On this example, that has about a 5% difference in speed - well worth it. Also, people reading your code don't know if you are using unchecked for truncation or perf - best to reserve it for the former and comment if the latter. - There's usually no point in trying to optimize an outer loop, in fact it can hurt you as you'll be representing things as primitives which just have to be re-boxed in order to become args to the inner call. The only exception is reflection warnings - you must get rid of them in any code that gets called frequently. Rich --~--~---------~--~----~------------~-------~--~----~ 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 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 -~----------~----~----~----~------~----~------~--~---