Home » Java » Will the "count limit" expression of a for-loop be evaluated only once, or on each iteration?

Will the "count limit" expression of a for-loop be evaluated only once, or on each iteration?

Posted by: admin December 28, 2021 Leave a comment

Questions:

If I invoke a method within a loop’s conditional statement, will it be called with each loop iteration?

For example:

for( int i = 0; i <= expensiveComputation(); i++ ) {
    // Do something.
}

Will I be performing expensiveComputation() on each iteration? Or will the result of expensiveComputation() be stored and used in each iteration at the same time the loop variable is initialised?

Should I instead re-write it to that:

int max = expensiveComputation();
for ( int i = 0; i <= max; i++ ) {
    // Do something.
}
Answers:

It will be invoked on each iteration, unless the compiler/optimizer decides that it has no side effects and can possibly eliminate the call as an optimization.

I mean, the compiler can’t just blindly store the value because a function in java, unlike a mathematical function, can have not only a return value, but also such side effects as printing something to some stream or changing some global state etc.

There is also another reason why the compiler can’t omit the call each iteration. The fact that your function doesn’t take any arguments does not mean that it will necessarily return the same value each time. It can, for example, input a number from a stream and return it, or it can randomly generate a number.

So the compiler needs to be extremely careful before it can safely eliminate the calls. So, if the function is expensive, you should definitely pre-store its value.

###

The second option is better specially if the computation does not require to be calculated at each iteration

If you suppose your loop is n length and you computation is O(n).

With the first solution, the complexity is O(n2) while the other is O(2n)

###

It may or may not be called on each iteration, depending on what bytecode the compiler feels like emitting. Most likely it will in fact be called each time.

If you want to ensure that it is not invoked on each iteration, then use the int max = ... version.

Why not simply test it yourself?

###

yes, you should cache your result in these situations, to ensure better performance.