> Nice writeup!

Thanks!

> ...and I hate to be picky, but you can probably compare
> strings sizes using a faster mechanism than the examples you
> gave.

Yeah, I figured I must have been doing something wrong, but I thought  
I'd leave it out there as a bit of ethnographic research :)

> So now we're comparing a boxed Integer 10 with an unboxed
> int returned by 'length'.  We can do better:

That's interesting... this is a case in which I thought HotSpot (or  
even Clojure's compiler) would automatically unbox: by the time it  
emits code for == it knows that it's comparing a primitive int to a  
constant non-primitive Integer (produced by the reader). Put another  
way: I would expect (== 10 10) to do no work at runtime, or at worst  
only primitive math, not boxed math.

Incidentally, this whole thing is a good example of a user expecting a  
sufficiently smart compiler: coming from Common Lisp one would expect  
the count implementation to be specialized for strings and other  
common types (essentially turning into a null check and a call  
to .length), and a similar optimization of ==. After all, the  
compiler(s) knows the input and output types of all the functions, and  
one of the arguments is constant. From that perspective, there's no  
reason why (== 10 (count some-string)) should not produce much the  
same bytecode as (== (int 10) (.length some-string)) -- both forms are  
equivalent, assuming no rebinding of count.

(While I'm very happy with Clojure, I can see the point of view of the  
people who come here and mouth off about Clojure not being as fast as  
Java. They're not strictly correct, but getting fast Clojure code does  
require some familiarity with which things its compiler will take care  
of, and which it leaves up to you.)

>
>       (defn t [] (dotimes [i 2e7] (== (int 10) (.length "123"))))
>       (time (t)) ; Watch HotSpot remove orders of magnitude, until:
>       --> "Elapsed time: 0.044282 msecs"
>
> That's really really fast.  That elapsed time is too small:
> we'd have to increase the test size to get any useful
> conclusion besides "really fast".  In fact, I almost wonder
> if HotSpot is somehow memoizing the expression all by
> itself.

It might be! In this case I suspect that something is inlining the  
result of (.length "123"), which is after all a compile-time constant.  
It might even be optimizing the entire contents of the loop away,  
replacing them with `false`.

> Anyway, Clojure's sets by themselves appear to be fast
> enough for you, or I assume you wouldn't have described them
> as "crazy fast".  However, *if* you discover later that
> they're are not fast enough you may be able to do length
> tests faster than you were thinking.  This may yet be
> a route to explore for improved overall speed.

You're quite right, and thanks for taking the time to continue the  
exploration!

My main conclusion from all this is that the JVM is really quick, and  
HotSpot is (by and large) a thing of wonder. There's not too much  
point in optimizing away a few hundred microseconds!

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