Performance Results



next up previous
Next: Interaction of Parameterization Up: Virtual Machine Extensions Previous: Runtime Extensions

Performance Results

 

We performed a few simple benchmarks to investigate the performance of our extended interpreter. These results must be considered preliminary, since we have not tuned our interpreter performance. Also, since the Java interpreter we were modifying runs at only a fraction of the speed of machine code, these results cannot be definitive. However, the results suggest that parameterized code adds little overhead to Java and offers performance improvements when its use is appropriate.

The results of our benchmarks are shown in Figures 8, 10, and 11. The benchmarks were run several times, so measurement variation is smaller than the significant digits shown. All run times are in seconds.

First, we confirmed that our extended interpreter did not significantly slow the execution of ordinary unparameterized code, by running the Java compiler javac (itself a large Java program) on both interpreters. As shown in Figure 8, the extended interpreter runs only 2% slower than the original interpreter on non-parameterized code.

Original interpreter: 8.5
Extended interpreter: 8.7


Figure 8: Java Compiler Speed (in seconds)

We also ran some small benchmarks to compare the speed of parameterized and non-parameterized code, using a simple parameterized collection class and some non-parameterized equivalents. In these comparisons, the code was almost identical, except for changes in type declarations and a dynamic cast. The code used repeatedly extracts an object from a parameterized collection and invokes a method on that object, as shown in Figure 9.


    Cell[Element] c = new Cell[Element]();
    c.add(new Element());
    for (i = 0; i < 1000000; i++) {
	Element t = c.get();
	t.do_method();
    }

Figure 9: Micro-benchmark code

In the first micro-benchmark, we compared the performance of the parameterized class Cell[T]; to a hard-wired ElementCell class, which can only contain objects of type Element. Both of these classes represent a simple collection that contains only one element. Using this simple collection isolates the performance effects that we want to measure. The hard-wired class, which is less generally useful, will obviously run faster. But as Figure 10 shows, there is only a 4% penalty for running parameterized code.

Parameterized:13.3
Hard-Wired Types:12.8
Using "Object":15.5


Figure 10: Collection Class Results

In the second micro-benchmark, we compared the parameterized class to the same collection class where the types of the components are all Object - the option for old-style Java code that the existing Java utility classes mostly follow. This version of the collection class gives up some static type checking, and also requires that the programmer write an explicit type cast when extracting values from the collection (in order to call do_method). Figure 10 shows that for our benchmark, this approach is 17% slower than using parameterized types.

invokewhere22.8
invokevirtual21.9
invokeinterface23.3


Figure 11: Invocation Speed

In the third micro-benchmark, we compared the speed of invoking where-routines (with the invokewhere bytecode), ordinary methods (with invokevirtual), and interface methods (with invokeinterface). Our test program intensively called these respective bytecodes. The results are shown in Figure 11. In our results, all three method invocation paths are within 6% of each other. This experiment represented a best case for invokeinterface, since its inline caching worked perfectly.

Although these performance results are produced by modifying an interpreter, we believe that the advantages of the extended bytecodes and of parameterized code will only increase with compiled machine code, since the interpreter tends to add a constant overhead to all operations. The slight overhead of Figure 8 is not intrinsic to parameterized code and can be eliminated with more careful implementation. The advantage of parameterized code shown in Figure 10 will be more dramatic, particularly since the cost of the runtime cast from Object will be relatively more expensive than method invocation.



next up previous
Next: Interaction of Parameterization Up: Virtual Machine Extensions Previous: Runtime Extensions



Andrew C. Myers, Joseph A. Bank, Barbara Liskov
Copyright © 1996 Association for Computing Machinery