We all know that Java performance is worse than natively compiled code, right? Well, even though I've found this to generally be the case, occasionally a Java Zealot will tell me how good the HotSpot JIT is and how it can make code even faster than natively compiled code. Likewise with C# and .NET. Don't get me wrong, I have nothing against Java or C#, especially from a productivity point of view. But I've remained skeptical about claims of "better than native" performance.

However, I've finally come across a concrete example of a program that Java executes faster: a simple recursive Fibonacci number calculator. On my computer, the C version calculates the 42nd Fibonacci in about 10 seconds, and the Java version takes about 6 seconds. Out of curiosity, I tried it again, with the JIT turned off (with the -Xint command line option). Unsurprisingly, this slows down the Java version significantly; it takes almost a minute and a half. Obviously, that JIT is doing some serious work!

Of course, this is a completely contrived example. Even if someone needed to generate Fibonacci numbers, no one would write his or her code this way, particularly if performance was an issue. But at least it demonstrates that the JIT can be effective. This program certainly plays right into the strengths of the JIT: it is a small piece of code, run over and over. It can be compiled at runtime, then further refined with feedback from each run.

As a side note, it is worth noting that the techniques used with Java's JIT can also be used with more traditional languages like C. In fact, some advanced optimizing compilers can take profiling data as input to generate better code, mirroring at compile-time what HotSpot does at runtime. I just happen to not have such a compiler.


fib.c, the C program:

#include <stdio.h>

static int fib(int i) {
    if (i == 0 || i == 1)
        return 1;
    return fib(i - 1) + fib(i - 2);
}

int main(int argc, char *argv[]) {
    printf("%d\n", fib(42));
    return 0;
}

Fib.java, the Java program:

public class Fib {
    private static final int fib(int i) {
        if (i == 0 || i == 1)
            return 1;
        return fib(i - 1) + fib(i - 2);
    }

    public static void main(String args[]) {
        System.out.println(fib(42));
    }
}