Clojure number crunching performance
I'm not sure whether this belongs on StackOverflow or in the Clojure Google group. But the group seems to be busy discussing numeric improvements for Clojure 1.2, so I'll try here:
http://shootout.alioth.debian.org/ has a number of performance benchmarks for various languages.
I noticed that Clojure was missing, so I made a Clojure version of the n-body problem.
The开发者_如何转开发 fastest code I was able to produce can be found here, and benchmarking it seems to be saying that for number crunching Clojure is
- factor ~10 quicker than Python/Ruby/Perl
- factor ~4 slower than C/Java/Scala/Ada
- approximately on par with OCaml, Erlang and Go
I'm quite happy with that level of performance.
My question to the Clojure gurus is
- Are there obvious improvements I have missed, either in terms of speed or in terms of code brevity or readability (without sacrificing speed)?
- Do you consider this to be representative of Clojure performance vs Python/Ruby/Perl on one hand and Java/C on the other?
Update
More Clojure 1.1 benchmark programs for the shootout here, including the n-body problem.
Not a flood of responses here :) but apparently some interest, so I'll try to answer my own question with what I've learned over the past few days:
- With the 1.1 optimization approach (Java primitives and mutable arrays) ~4x slower than optimized Java is about as fast as it goes.
- The 1.2 constructs
definterface
anddeftype
are more than twice as fast, coming within ~1.7x (+70%) of Java with shorter, simpler and cleaner code than for 1.1.
Here are the implementations:
- Clojure 1.1 approach
- Clojure 1.2 approach
More details including "lessons learned", JVM version and profiling screenshots.
Subjectively speaking, optimizing the 1.2 code was a breeze compared to optimizing 1.1, so this is very good news for Clojure number crunching. (Actually close to amazing :)
The 1.2 testing used the current master branch, I did not try any of the new numeric branches. From what I can gather the new ideas currently being discussed
- may make non-optimized numerics faster
- may speed up the 1.1 version of this benchmark
- will probably not speed up the 1.2 version, it is already as "close to the metal" as it is likely to get.
Disclaimers:
- Clojure 1.2 is not released yet, so 1.2 benchmark results are preliminary.
- This is one particular benchmark on physics calculations. It is relevant to floating point number crunching, but irrelevant to performance in areas like string parsing, concurrency or web request handling.
I wonder if Cantor might be of use to you -- it's a high performance math library for Clojure. Also see this thread on the Google group, which is about a similar project in the context of the new primitive arithmetic stuff.
This is a slightly old question and the existing answers are somewhat out of date, so I'd like to add an update as of mid-2013 for those interested in "number crunching" in Clojure
There has been a lot happening in the Clojure Numerical computing space:
- Clojure 1.5 is now out, which has a lot of improved support for numerical operations. In most cases, it's now possible to get very close to pure Java speed
- A dedicated newsgroup - Numerical Clojure
- core.matrix now provides an idiomatic API for matrix maths / numerical computing that supports multiple backend implementations (including native BLAS libraries)
Disclaimer: I'm a maintainer / contributor to several of the above.
精彩评论