alain.janinm alain.janinm - 1 year ago 87
Java Question

JVM option to optimize loop statements

I've been told at school that it's a bad practice to modify the index variable of a

for loop

Example :

for(int i = 0 ; i < limit ; i++){
i+=2; //bad
limit+=2; //bad

The argument was that some compiler optimization can optimize the loop and not recalculate the index and bound at each loop.

I 've made some test in
and it seems that by default index and bound are recalculate each time.

I'm wondering if it's possible to activate this kind of feature in the
JVM HotSpot

For example to optimize this kind of loop :

for(int i = 0 ; i < foo.getLength() ; i++){ }

without having to write :

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

It's just an example I'm curious to try and see the improvments.


According to Peter Lawrey answer why in this simple example the JVM don't inline

public static void main(String[] args) {
Too t = new Too();
for(int j=0; j<t.getLength();j++){

class Too {

int l = 10;
public Too() {
public int getLength(){
return l;

In the output "test" is print 10 times.

I think it could be nice to optimize this kind of execution.

EDIT 2 :
Seems I made a misunderstood...

I have remove the
and indeed the profiler tell me that the method
is not even call once in this case.

Answer Source

I 've made some test in java and it seems that by default index and bound are recalculate each time.

According to the Java Language Specification, this:

for(int i = 0 ; i < foo.getLength() ; i++){   }

means that getLength() is called on each loop iteration. Java compilers are only allowed to move the getLength() call out of the loop if they can effectively prove that it does not alter the observable behaviour. (For instance, if getLength() simply returned the same value from the same variable each time, then there is a good chance the the JIT compiler can inline the call and then deduce that it can do the hoisting optimization. But if getLength() involves getting the length of a concurrent or synchronized collection, the chances are slim that the optimization will be permitted ... because of potential actions by other threads.)

So that's what a compiler is allowed to do.

I'm wondering if it's possible to activate this kind of feature in the JVM HotSpot?

The simple answer is No.

You seem to be suggesting a compiler switch that tells / allows the compiler to ignore the JLS rules. There is no such switch. Such a switch would be a BAD IDEA. It would be liable to cause correct/valid/working programs to break. Consider this:

class Test {
   int count;

   int test(String[] arg) {
       for (int i = 0; i < getLength(arg); i++) {
           // ...
       return count;

   int getLength(String[] arg) {
       return arg.length;

If the compiler was permitted to move the getLength(arg) call out of the loop, it would change the number of times that the method was called, and therefore change the value returned by the test method.

Java optimizations that change the behaviour of a properly written Java program are not valid optimizations. (Note that multi-threading tends to muddy the waters. The JLS, and specifically the memory model rules, permit a compiler to perform optimizations that could result in different threads seeing inconsistent versions of the application's state ... if they don't synchronize properly, resulting in behaviour that is incorrect from the developer's perspective. But the real problem is with the application, not the compiler.)

By the way, a more convincing reason that you shouldn't change the loop variable in the loop body is that it makes your code harder to understand.