Here's my theory.

In your when example, "when" is a macro that is expanded to an "if"
special form. Your other examples, however, wrap your code in a
function call.

Now, functions in Clojure can't really take primitive arguments, so in
spite of your coercion efforts Clojure introduces boxing in your loop
and this is what slows you down.

A work-around is to either use a (def variable ...) or something like this:

(let [x (time (loop [i (int 0)] (if (< i (int 30000000)) (recur (inc
i)) i)))] (prn x))

How does that sound?

On Fri, Jan 16, 2009 at 5:43 AM, Jason Wolfe <jawo...@berkeley.edu> wrote:
>
> I was doing some microbenchmarking earlier, and I noticed some very
> very weird anomalies.   If anyone could shed some light on what's
> going on that would be awesome. (I'm using the latest SVN, and have
> verified this on a totally clean repl).
>
> Simplified as much as possible, the heart of what I observed is:
>
> user> (prn (time (loop [i (int 0)] (if (< i (int 30000000)) (recur
> (inc i)) i))))
> "Elapsed time: 4247.477 msecs"
> 30000000
> nil
>
> user> (time (loop [i (int 0)] (if (< i (int 30000000)) (recur (inc i))
> i)))
> "Elapsed time: 128.37 msecs"
> 30000000
>
> Weird, right?  The prn is *outside* the loop, and yet it still affects
> the timing somehow.  Maybe this is something specific to printing?
> Nope:
>
> user> (first (time (loop [i (int 0)] (if (< i (int 30000000)) (recur
> (inc i)) [i]))))
> "Elapsed time: 4264.847 msecs"
> 30000000
>
> user> (time (loop [i (int 0)] (if (< i (int 30000000)) (recur (inc i))
> [i])))
> "Elapsed time: 130.099 msecs"
> [30000000]
>
> But, some other expressions around the "time" don't affect it in the
> same way:
>
> user> (when (time (loop [i (int 0)] (if (< i (int 30000000)) (recur
> (inc i)) [i]))) 12)
> "Elapsed time: 130.236 msecs"
> 12
>
> In case you were wondering, this has nothing to do with the "time"
> macro.
>
> user> (first (loop [i (int 0)] (if (< i (int 30000000)) (recur (inc
> i)) [i])))
> ; ...  4 seconds pass on my stopwatch ...
> 30000000
>
> And the slowness is by a multiplicative, not additive factor:
>
> user> (first (time (loop [i (int 0)] (if (< i (int 60000000)) (recur
> (inc i)) [i]))))
> "Elapsed time: 8576.649 msecs"
> 60000000
>
> user> (time (loop [i (int 0)] (if (< i (int 60000000)) (recur (inc i))
> [i])))
> "Elapsed time: 250.407 msecs"
> [60000000]
>
> I'm at a total loss for what's going on.  Anyway, I'll stop here for
> now in case I'm missing something stupid or obvious.
>
> Thanks for your help!
> Jason
>
> >
>



-- 
Venlig hilsen / Kind regards,
Christian Vest Hansen.

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