Richards is an interesting medium-sized language benchmark (400-500 lines). It simulates the task dispatcher in the kernel of an operating system. The original version was written in BCPL by Martin Richards at Cambridge University, England. It has since been translated into many languages, including C, C++ and Smalltalk.
One translation into the Java programming language is due to Jonathan Gibbons, based on a C version by Mick Jordan. This character of this translation is very similar to that of the original BCPL program by Martin Richards, and does not take advantage of the object-oriented features of Java.
I wrote a different version in Java, derived from a Smalltalk implementation by L. Peter Deutsch. Like the Smalltalk version, this is much more object-oriented, and has quite different performance characteristics. This version, in C++ (by Urs Hölzle), Smalltalk and Self, has been used as the basis for comparison in all the papers published by the Self project.
After creating the latter version, I was intrigued by the performance difference between the two Java translations, and decided to study the two versions more closely. In the end I created seven different versions of this benchmark, each exhibiting a different stylistic element and performance characteristic.
The different versions span a range in object-orientedness. One version is the `natural' translation from C code, without particular attention to source-level optimization. Another version uses features of the Java language to improve performance. A third is like the C-based version except that the program state is not as highly encoded.
The other four versions are based on the Smalltalk original, from which a C++ version was also derived. One is a `natural' translation from the C++, taking the most obvious mapping from C++ to Java. The others are closer to the Smalltalk version, in that all instance variables are accessed via methods; they vary in how those methods are declared.
The state within these objects is represented by public instance variables, which are directly accessed where necessary.
This is a natural translation from the C++ version of Deutsch, which in turn was based on the Smalltalk version. Note, however, that where C++ methods default to being statically bound, Java methods default to being virtually bound. This is also the closest to the versions in Smalltalk and Self.
Versions 1 and 2 (richards_gibbons and richards_gibbons_final) are almost the same in performance, the extra finals buying little speedup. Version 3 (richards_gibbons_no_switch) is slightly slower. Version 4 (richards_deutsch_no_acc) is slightly slower again. However, when virtual accessors are introduced in #5 (richards_deutsch_acc_virtual) performance degrades significantly. Using finals (#6, richards_deutsch_acc_final) can recover this performance. Using interfaces (#7, richards_deutsch_acc_interface) is as bad as using virtuals, if not slightly worse.
Compare this with the results for C++ (below). There are no results for #2 (it is the same as #1) and #7 (there are no interfaces in C++).
Note that an all-virtual program is much slower in C++ compared to the non-virtual versions (#5 vs #6). Because of this, C++ programmers tend to use virtuals sparingly. When translating from C++ to Java extra effort must be expended to make methods final, as the default binding in Java is virtual.
Contrast this with an experimental implementation of the JavaTM Virtual Machine, called Pep, which was implemented on the Self Virtual Machine (do not compare absolute times as these runs are on a much slower machine).
The Self Virtual Machine performs adaptive optimization and is even capable of inlining virtuals. Note that the curve is essentially flat, with the exception of #1 (Self has no good way of implementing a switch statement). This suggests that adaptive optimization will work for Java (some programs, at least). More details can be found in "Design and Implementation of Pep, a Java Just-In-Time Translator", by Ole Agesen, published in the Theory and Practice of Object Systems, 3(2), 1997, pp.127-155. Similar techniques are used in the `HotSpot' Java VM.