Java - Difference between for loop terminating expression

1.6k views Asked by At

I'm just curious: Is there a difference on speed and performance between this two loops implementation? Assume that size() method returns the length of the array,collection, or object that handles a group of elements (actually it's from XOM api).

Implementation 1:

int size = someArray.size();
for (int i = 0; i < size; i++) {
    // do stuff here
}

Implementation 2:

for (int i = 0; i < someArray.size(); i++) {
    // do stuff here
}
6

There are 6 answers

0
Peter Lawrey On BEST ANSWER

From a performance point of view, there is little difference. This is because a loop can be optimized so that the size() lookup is inlined, resulting in very little performance difference.

The main difference is if the size changes while looping. The first case will try to iterate a fixed number of times. In the second case, the number of iterations will depend on the final size().

10
bestsss On

The 1st snippet is bound to execute faster since it calls size() once only. The 2nd snippet calls size() N times. Depending on the impl. it might pose significant penalty, esp. if the compiler finds hard to inline the method and/or the size() method doesn't just return non-volatile variable, etc.

I'd have rewritten it like for(int i=0, s=someCollection.size(); i<s; i++)

Note: arrays don't have size() method.

4
JB Nizet On

Yes, there is a difference. In the first loop, the size() method is only called once. In the second one, it's called at each iteration.

If the iteration modifies the size of the collection (which is very very uncommon), the second one is needed. In most cases, you should prefer the first one, but limit the scope of the size variable :

for (int i = 0, size = someArray.size(); i < size; i++) {
    // ...
}

But most of the time, you should prefer the foreach syntax anyway :

for (Foo foo : collection) {
    // ...
}

which will iterate over the array or collection efficiently, even for a LinkedList for example, where indexed access is not optimal.

0
irreputable On

Don't worry about it, JVM optimization is very aggressive these days.

Use the 2nd form, for it's more readable, and most likely as fast. Premature optimization yada yada.

And when you do need to improve speed, always profile first, don't guess.

It is extremely unlikely that caching size() in a local variable could benefit your app noticeably. If it does, you must be doing simple operations over a huge dataset. You shouldn't use ArrayList at all in that case.

2
Tomasz Nurkiewicz On

Maybe it is worth to note that this construct:

for (String s : getStringsList()) {
    //...
}

invokes getStringsList() only once and then operates on iterator behind the scenes. So it is safe to perform lengthy operations or change some state inside getStringsList().

0
Nikhil Kumar On

Always avoid anything that can be done outside of the loop like method calls, assigning values to variables, or testing for conditions.

Method calls are more costly than the equivalent code without the call, and by repeating method calls again and again, you just add overhead to your application.

Move any method calls out of the loop, even if this requires rewriting of the code.

Benefits :-

Unless the compiler optimizes it, the loop condition will be calculated for each iteration over the loop.

If the condition value is not going to change, the code will execute faster if the method call is moved out of the loop.

Note :-

If the method returns a value that will not change during the loop, then store its value in a temporary variable before the loop.

Hence its value is stored in a temporary variable size outside the loop, and then used as the loop termination condition.