Friday, June 05, 2009

JavaOne Talk: Performance Comparisons of Dynamic Languages on the Java Virtual Machine

Below are the sldies. Major thanks to Charlie Nutter for great feedback and advice on the Ruby code and tuning JRuby performance. Thanks to Chouser and Timothy Pratley for help with the Clojure code. And major thanks to Brian Frank for help with the Fan code.


Matthew Hall said...

Interesting stuff.

Just out of curiosity, what JIT mode did you use to run these performance profiles (i.e. server, client, interpreted)?

Michael Galpin said...

Good question Matthew. The JVM used was HotSpot 1.6.0_14, 64-bit for Windows. The 64-bit JVMs are server JVMs only, no client mode. Each test ran with 2 GB of heap, to minimize (eliminate) any garbage collections. Also, each test had a "warm-up" as well, where the same computation that was done in the main algorithm was executed in a loop to induce JIT. However, Charlie pointed out that on the word sort, I probably did not run a long enough loop on the warm up, as is evidenced by the humps at the beginning of the graphs.

Scot said...

You could make the Scala example far more concise (if you use recursion):

def primes(n: Int): List[Int] = {
def nomults(s: Int, xs: Seq[Int]): List[Int] = (for (x <- xs if x % s != 0) yield x).toList
def sieve(xs: List[Int]): List[Int] = {
if (xs.isEmpty) xs
else {
val p = xs.first
val nxs = nomults(p, xs drop 1)
p :: sieve(nxs)

val odds = nomults(2, 2 to n)
2 :: sieve(odds)

println( primes(100) )

And even that's not as concise as possible. As the code above will get screwed up, you can view it here.

Daniel said...

I saw some serious problems with the algorithms used. The first Scala one was unrecognizable as a Scala program -- this is the first time I actually saw "while" being used in Scala outside a "while(true)" loop.

On the second algorithm I note that Fan uses compareIgnoreCase, which is also available at the very least to Java, but in Java (and some others), it is used a .toLowerCase instead. This causes repeated creation of new strings, while compareIgnoreCase doesn't, saving quite some time.

Scala's second algorithm not only suffers for the same reason, but doesn't even make use of BufferedSource instead of Source, so as to be more directly comparable to Java. Also, the File definition is useless, and the whole algorithm is a bit suspicious, though I don't know how much difference in performace could be had. Anyway, flatMap should have been used instead of foreach, the assignment to words dropped, sort appended after flatMap, and the whole thing used as initializer for words. A convertion to projection might be indicated after getLines, but I don't think so.

Converting to List should probably only be done after sort -- split will return an array, which I suspect will have better sorting performance, and split already return arrays.

These are nits, though. The toLowerCase vs compareIgnoreCase issue isn't.

Generic Viagra said...

Putting on a conference like JavaOne is no small task. The centerpiece of the conference is, of course, the technical sessions, and numerous reviewers spend a great deal of time combing through the proposals. This year, we had over 1300 proposals -- more than five times as many proposals as we had slots!