In one sense benchmarking Kawa is meaningless, because performance will vary so much depending on the underlying Java implementation. One can even take the compiled bytecode files and translate them to native code, factoring out the Java interpreter altogether. For example, the Gcc-based Java implementation GCJ [GccJava]; can speed up compiled Kawa code substantially.
While the goal of Kawa is not maximum performance, it would be
reassuring if its speed is at least comparable to other Scheme
implementations. So I took three of the old Gabriel benchmarks
(as I found them in the Stalin distribution, by Jeffrey Mark Siskind
“Qobi”). I ran them on an UltraSparc running Solaris 2.6.
I compared Kawa, running under JavaSoft's JDK 1.1.5,
with two representative Scheme implementations:
Guile is the Free Software Foundation's Scheme implementation.
It is an interpreter based on the heavily-tuned SCM (written
by Aubrey Jaffer). Scheme48 (written by Richard Kelsey and Jonathan Rees)
compiles to a Scheme-specific bytecode, which is then interpreted
(Note that Kawa is doing the various inlining optimizations mentioned earlier;
this makes a substantial difference, but could break some unusual programs.)
The Puzzle benchmark is based on the old Forrest Baskett benchmark,
and uses vectors and do
-loops extensively.
Traverse creates and traverses a tree structure.
Takl is the Takeuchi function using lists as counters.
Kawa | Scheme48 | Guile | |
---|---|---|---|
Puzzle | 21s | 14s | 67s |
Traverse | 18s | 14s | 46s |
Takl | 81s | 36s | 87s |
These results show Kawa beating Guile on all benchmarks, the first two substantially. Scheme48 is faster, but by less than a factor of two (on average). It is interesting that Kawa does as well as it does, using a bytecode designed for Java, as opposed to Scheme48's bytecodes tailored specifically to Scheme.