On Tue, May 10, 2011 at 10:14 PM, Carl Cotner <carl.cot...@gmail.com> wrote:
> Thanks for your thorough reply, Ken.

You're welcome.

>> 3: Technical speedups. Avoid function calls inside inner loops, which
>> cause boxing and require var dereferencing. Fold divQ into primes,
>> since it's only used once in there.
>
> Just to make sure I understand: type hints don't cause Clojure to
> optimize these things out by itself? (I had been supposing that type
> hints would propagate through functions and function calls so that
> boxing, for example, would be avoided.)

Not in Clojure 1.2. 1.3 can sometimes avoid boxing across function
calls, but I think you have to do specific things when defining the
called functions to support it.

There's also no type inference across function call boundaries. Hint
the arguments of every function where it will matter for speed, or use
*warn-on-reflection* to find the problem areas with non-primitives
lacking type hints and hint them.

>> 6: Benchmarking accuracy. Don't include the JIT compilation, the
>> overhead of calling the primeQ function and of the benchmarking
>> itself, or, God forbid, the JVM startup time; do a few thousand
>> repetitions of the whole thing with a small (e.g. four-digit) prime to
>> get the JITting done and then do a big number several times and
>> average the results, using a timing macro of some sort from inside the
>> running Clojure session to avoid counting the JVM startup time. The
>> timing/call overhead will be lost in the noise if the number tested in
>> the timed runs is big enough.
>
> Does the built-in Clojure (time ...) expression that I used from the
> SLIME REPL actually include things like JVM startup time?
>
>  user> (time (primeQ 71378569))
>  "Elapsed time: 11047.721488 msecs"

Anything run from the REPL won't include JVM startup time (unless it
launches a separate JVM process and waits for it to do something).

On the other hand the time macro prints a string to stdout; for more
complex benchmarking (such as running several trials, ignoring the
first few which weren't JITted yet and dropping outliers and then
averaging the rest) you want something that discards the timed
expression's return value and returns the time itself. It's not hard
to slap something like that together with defmacro.

> Also, do you happen to know of a good reference for how/when the JVM
> does JIT compilation?

No, sorry.

Generally, running a loop a few times will JIT all the heavy number
crunching in it, and then you'll get consistent, JIT-optimized times
if you run it a few more times.

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