This is probably a silly question, well outside the scope of this conversation (but maybe not, and I didn't want to start a whole thread on it).
Is it much much easier to make byte code than assembly code? I mean, I understand why running on a VM makes sense as far as instantly inheriting all the massive amounts of things out here for Java .... but would it be possible to shoot for something down the road that, behind the scenes, uses jvm whenever you say, "import" . . .and writes and compiles assembler whenever you are doing purely algorithmic things? In a way, I guess what I'm saying is that this was a fix that helped the hotspot compiler along. But (and I'm TOTALLY ignorant about all of this so maybe I should do more reading before asking the question) that technology is a moving target and varies from one VM to another. It's sort of analogous to the discussion on why the Jython approach is problematic because it's got to stay in sync with Python. Is this a silly question? Thanks. On Fri, Jan 16, 2009 at 8:59 AM, Rich Hickey <richhic...@gmail.com> wrote: > > > > On Jan 16, 5:15 am, Christian Vest Hansen <karmazi...@gmail.com> > wrote: > > 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 > > > > The bytecode produced for the loop is exactly the same in both cases. > It seems the presence of first (or really anything) on the stack > during looping causes HotSpot to bail on optimizing. This is a case > where the bytecode is unlike any produced by javac (in Java, loops > cannot be expressions). > > For now, I've made it so that when a loop occurs as an expression it > is lifted out into a fn, and the performance is identical. > > SVN 1216 - thanks for the report. > > 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 -~----------~----~----~----~------~----~------~--~---