开发者

Java performance: arraylength vs iload

for (int i=0; i<arr.length; i++) {
}

This will result in a code:

gets开发者_C百科tatic   #4;
arraylength

While the following code:

int length = arr.length;
for (int i=0; i<length; i++) {
}

will be compiled as:

iload_3

Is there a difference between the two snippets? Which code runs faster?

As you an see, the array is a static member in my case. Static and final to be exact. Taking JIT optimization into account, a basic optimizer can sense that and hard code the length of the array into the machine code of the method. It is much harder to follow this logic with a local variable (second case), so one would think there is a greater chance that the first one will be optimized than the second.


As it's static and final, I suspect it could hard-code the length, although I'm not sure it would go that far. But the JIT compiler may well still be able to do better with the first form than the second.

In particular, if it can detect that the array doesn't change within the loop, it can avoid evaluating the length more than once and remove array bounds checks within the loop - it can validate that you're never going to access the array outside the range [0, length).

I would hope that by now, decent JITs would notice the second form too - but I'd still prefer the first form for readability, and I'd want evidence of it not performing as well as the second before changing to that one.

As ever, write the most readable code first, but measure it against performance requirements.


Is there a difference between the two snippets?

It depends. If the arr variable is updated in the body of the loop, then the two code snippets are semantically different.

Which code runs faster?

It is impossible to say. It depends on the native code generated by the JIT compiler, and that can vary from one patch release to the next. The only know for sure is to dump the native code and examine it in detail, or benchmark the code. But either way, the difference is usually too small to be worth worrying about.


One optimisation the JVM does is to avoid bounds checking the array on every access. Instead it can bounds check the first and last value instead.

However, it is possible some micro-optimisation will confuse the JVM and you will get slower less optimised code in the end.

The form I use when micro-optimising is

for (int i = 0, length = methodCall(arr); i < length; i++) {
   // use the array.
}

I prefer to use the simplest and most obvious solution to a problem because the JVM is most likely to optimise this use case best.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜