Angeline & I went up to the not-quite-frozen north last week to visit her fam for Christmas. I shall account for time spent there in a future entry a few days from now, but not right now because the pictures I want to post are on my camera that I left there.
Instead, I’ll continue to post about boring technical subjects. Today: one example of sucky Java performance (a topic which hardly anyone in the Java community cares about, apparently). I had a disagreement of opinion with a co-worker recently, as I was coming across code written by a 3rd person that went like:
public void getBar() { return this.bar; }
public void doSomething() {
getBar().frob();
getBar().xyzzy();
getBar().baz();
}
I remarked that this sort of programming is not only extra typing, but performs poorly because inside doSomething we are now making six method calls instead of only the three we need. My co-worker suggested the Java compiler was smart enough to inline getBar(). I was skeptical for two reasons: first that getBar is public, so in order to allow subclasses to override it, it has to be in the Java-equivalent of a vtable, like every other Java method. Second, I’ve looked at the output of javac and it is really quite dumb.
So, I decided to make it easy on the compiler in a test program to see (excerpt):
private static final String blah="blah";
private final String getBlah() { return blah; }
public void doit() { System.out.println(getBlah()); }
There’s no way for a subclass to override getBlah or the value it returns; however, the code generated is:
public void doit();
Code:
0: getstatic #3; //Field java/lang/System.out:Ljava/io/PrintStream;
3: aload_0
4: invokespecial #4; //Method getBlah:()Ljava/lang/String;
7: invokevirtual #5; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
10: return
Obviously, the final keyword does nothing. Now, I don’t know much about how the JVM/JIT will further optimize this, but this can’t be more efficient than a simple load of the variable onto the stack. We have to store this
on the stack for one thing, and the JVM needs to store a return address somewhere. A small effect, sure, but why throw away performance?
Maybe I’ll be evil and start asking why Java should have the ‘virtual’ keyword in interviews.