Hugh Winkler holding forth on computing and the Web

Saturday, January 03, 2009

Clojure vs JavaFX Script: only 5x slower!

Chris Oliver compares his JavaFX script to JRuby and Groovy and finds JavaFX 25 times faster.

I failed to get JavaFX compiler running on my Ubuntu, but I easily ran Chris's JRuby 1.1.6 test; so for calibration, my laptop comes in at 3:52, vs 4:22 on Chris's machine. Presumably we can scale results on my machine by 1.13.

Here's my Clojure version of the test:


(defn tak [#^Integer x #^Integer y #^Integer z]
(if (>= y x)
z
(recur (tak (- x 1) y z)
(tak (- y 1) z x)
(tak (- z 1) x y))))

(dotimes [n 1000] (tak 24 16 8))



It runs in about 50 seconds, or 56 after normalizing to Chris' machine speed. This puts Clojure north of JRuby and Groovy, but still 5 times slower than JavaFX.

If you remove the type hints, it runs in 4 minutes, or about the same time as JRuby -- and about 4 or 5 times slower than with type hints.

4 comments:

Anonymous said...

(defn tak [#^Integer x #^Integer y #^Integer z]
(if (<= y x)
z
(recur
((unchecked-dec x) y z)
((unchecked-dec y) z x)
((unchecked-dec z) x y))))

(dotimes [n 1000] (tak 24 16 8))

hughw said...

That code is wrong -- the comparison goes the other way -- and when I fixed that and run it, I get ClassCastException.

Matthias Benkard said...

Anonymous probably meant to say:

(defn tak [#^Integer x #^Integer y #^Integer z]
(if (>= y x)
z
(recur (tak (unchecked-dec x) y z)
(tak (unchecked-dec y) z x)
(tak (unchecked-dec z) x y))))

Anonymous said...

With Clojure 1.3 it is much faster then original if you use:
(defn ^long tak [^long x ^long y ^long z]
(if (>= y x)
z
(recur (long (tak (- x 1) y z))
(long (tak (- y 1) z x))
(long (tak (- z 1) x y)))))