Bytecode optimization in Java

I learnt something new about bytecode optimization today. In languages like C and C++, if you’re really concerned about efficiency, you can drop into assembly mode and write specific assembly code instead of relying on the compiler to convert your C/C++ code into assembly (compilers can optimize, but not as well as humans in all cases).

I saw a question on Stackoverflow today that talked about the getfield opcode in the context of the trim() method in the String class. In the trim() method, you have the following comments:

int off = offset;      /* avoid getfield opcode */
char[] val = value;    /* avoid getfield opcode */

The author of the question wanted to know what these comments mean. This question seemed pretty interesting to me and so I went and did some research. I found out that getfield is an operation that lets you get access to the member variable/field of a class. This operation is fairly expensive as it involves indexing into the runtime constant pool. Performing this operation a few times does not really incur a performance hit. It is when you perform the operation multiple times, that performance becomes an issue. You can see this from the next few lines of code:

while ((st < len) && (val[off + st] <= ' ')) { st++; } while ((st < len) && (val[off + len - 1] <= ' ')) { len--; } [/sourcecode] Now if the author of the trim() method hadn’t assigned offset and value to local variables, a getfield operation would be performed every time the loop-condition is tested. This is obviously inefficient. Therefore, the author assigned the the values of offset and val into the local variables off and val. So now, instead of getfield you have iload (for off anyway), which performs much faster.