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

Reply via email to