why is the enhanced for loop more efficient than the normal for loop
I read that the enhanced for loop is more efficient than the normal for loop here:
http://developer.android.com/guide/practices/performance.html#foreach
When I searched for the difference between their efficiency, all I found is: In case of normal for loop we need an extra step to find out the length of the array or size etc.,
for(Integer i : list){
....
}
int n = list.size();
for(int i=0; i < n; ++i){
....
}
But is this the only reason, the enhanced for loop is better than the normal for loop? In that case better use the normal for loop because of the slight complexity in understanding the enhanced for loop.
Check this for an interesting issue: http://www.coderanch.com/t/258147/java-programmer-SCJP/certification/Enhanced-Loop-Vs-Loop
Can any one please explain the internal implementation of these two types of for loops, or explain other reasons to use the enhanced for loop?
It's a bit of an oversimplification to say that the enhanced for loop is more efficient. It can be, but in many cases it's almost exactly the same as an old-school loop.
The first thing to note is that for collections the enhanced for loop uses an Iterator
, so if you manually iterate over a collection using an Iterator
then you should have pretty much the same performance than the enhanced for loop.
One place where the enhanced for loop is faster than a naively implemented traditional loop is something like this:
LinkedList<Object> list = ...;
// Loop 1:
int size = list.size();
for (int i = 0; i<size; i++) {
Object o = list.get(i);
/// do stuff
}
// Loop 2:
for (Object o : list) {
// do stuff
}
// Loop 3:
Iterator<Object> it = list.iterator();
while (it.hasNext()) {
Object o = it.next();
// do stuff
}
In this case Loop 1 will be slower than both Loop 2 and Loop 3, because it will have to (partially) traverse the list in each iteration to find the element at position i
. Loop 2 and 3, however will only ever step one element further in the list, due to the use of an Iterator
. Loop 2 and 3 will also have pretty much the same performance since Loop 3 is pretty much exactly what the compiler will produce when you write the code in Loop 2.
I am myself surprised in a little experiment i did today with above mentioned points.
So what i did was that i inserted a certain number of elements to a linked list and iterated through it using the above mentioned three methods 1)using advanced for loop 2) using Iterator 3) using simple loop and get()
I guess programmers such as you guys can better understand what i did by seeing the code.
long advanced_timeElapsed,iterating_timeElapsed,simple_timeElapsed;
long first=System.nanoTime();
for(Integer i: myList){
Integer b=i;
}
long end= System.nanoTime();
advanced_timeElapsed=end-first;
System.out.println("Time for Advanced for loop:"+advanced_timeElapsed);
first=System.nanoTime();
Iterator<Integer> it = myList.iterator();
while(it.hasNext())
{
Integer b=it.next();
}
end= System.nanoTime();
iterating_timeElapsed=end-first;
System.out.println("Time for Iterating Loop:"+iterating_timeElapsed);
first=System.nanoTime();
int counter=0;
int size= myList.size();
while(counter<size)
{
Integer b=myList.get(counter);
counter++;
}
end= System.nanoTime();
simple_timeElapsed=end-first;
System.out.println("Time for Simple Loop:"+simple_timeElapsed);
The results where not what i expected . Following is the graph of time elapsed in 3 cases.
Y axis-time elapsed
X axis-test case
test case1:10 inputs
test case2:30 inputs
test case3:50 inputs
test case4:100 inputs
test case5:150 inputs
test case6:300 inputs
test case7:500 inputs
test case8:1000 inputs
test case9:2000 inputs
test case10:5000 inputs
test case11:10000 inputs
test case12:100000 inputs
Here you can see that simple loop performs way better than others.if you find any errors in the code above , do reply and i will check again. will update on this further after i dig through bytecode and see what is happening under the hood. My apologies for such a long response but i like to be descriptive. Philip
I read that enhanced for loop is efficient than normal for loop.
Actually sometimes its less efficient for the program, but most of the time its exactly the same.
Its more efficient for the developer, which is often far more important
A for-each loop is particularly useful when iterating over a collection.
List<String> list =
for(Iterator<String> iter = list.iterator(); list.hasNext(); ) {
String s = list.next();
is more easily written as (but does the same thing as, so its no more efficient for the program)
List<String> list =
for(String s: list) {
Using the "old" loop is slightly more efficient when access a randomly accessible collection by index.
List<String> list = new ArrayList<String>(); // implements RandomAccess
for(int i=0, len = list.size(); i < len; i++) // doesn't use an Iterator!
Using a for-each loop on a collection always uses an Iterator which is slightly less efficient for random access lists.
AFAIK, use a for-each loop is never more efficient for the program, but like I said the efficiency of the developer is often far more important.