Is there a performance difference between a for loop and a for-each loop?
From Item 46 in Effective Java by Joshua Bloch :
The for-each loop, introduced in
release 1.5, gets rid of the clutter
and the opportunity for error by
hiding the iterator or index variable
completely. The resulting idiom
applies equally to collections and
arrays:// The preferred idiom for iterating over collections and arrays
for (Element e : elements) {
doSomething(e);
}
When you see the colon (:), read it as
“in.” Thus, the loop above reads as
“for each element e in elements.” Note
that there is no performance penalty
for using the for-each loop, even for
arrays. In fact, it may offer a slight
performance advantage over an ordinary
for loop in some circumstances, as it
computes the limit of the array index
only once. While you can do this by
hand (Item 45), programmers don’t
always do so.
Java loop efficiency (for vs. foreach)
From section 14.14.2 of the JLS:
Otherwise, the Expression necessarily has an array type, T[]. Let L1 ... Lm be the (possibly empty) sequence of labels immediately preceding the enhanced for statement. Then the meaning of the enhanced for statement is given by the following basic for statement:
T[] a = Expression;
L1: L2: ... Lm:
for (int i = 0; i < a.length; i++) {
VariableModifiersopt Type Identifier = a[i];
Statement
}
In other words, I'd expect them to end up being compiled to the same code.
There's definitely a clear winner: the enhanced for loop is more readable. That should be your primary concern - you should only even consider micro-optimizing this sort of thing when you've proved that the most readable form doesn't perform as well as you want.
Performance Difference For-Loop Foreach
First things first - for-each
is nothing but syntactic sugar for Iterator
. Read this section of JLS. So, I will address this question as a simple FOR loop vs Iterator.
Now, when you use Iterator
to traverse over a collection, at bare minimum you will be using two method - next()
and hasNext()
, and below are their ArrayList
implementations:
public boolean hasNext() {
return cursor != size;
}
@SuppressWarnings("unchecked")
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = I]; // hagrawal: this is what simple FOR loop does
}
Now, we all know the basic computing that there will be performance difference if on the processor I have to just execute myArray[i]
v/s complete implementation of next()
method. So, there has to be a difference in performance.
It is likely that some folk might come back strongly on this, citing performance benchmarks and excerpts from Effective Java, but the only other way I can try to explain is that this is even written in Oracle's official documentation - please read below from RandomAccess
interface docs over here.
It is very clearly mentioned that there will be differences. So, if you can convince me that what is written in official docs is wrong and will be changed, I will be ready to accept the argument that there is no performance difference between simple FOR loop and Iterator or for-each.
So IMHO, correct way to put this whole argument is this:
- If the collection implements
RandomAccess
interface then simple FOR loop will perform (at least theoretically) better than Iterator or for-each. (this is what is also written in RandomAccess docs) - If the collection doesn't implement
RandomAccess
interface then Iterator or for-each will perform (for sure) better than simple FOR loop. - However, for all practical purposes, for-each is the best choice in general.
In .NET, which loop runs faster, 'for' or 'foreach'?
Patrick Smacchia blogged about this last month, with the following conclusions:
- for loops on List are a bit more than 2 times cheaper than foreach
loops on List.- Looping on array is around 2 times cheaper than looping on List.
- As a consequence, looping on array using for is 5 times cheaper
than looping on List using foreach
(which I believe, is what we all do).
Javascript efficiency: 'for' vs 'forEach'
for
for
loops are much more efficient. It is a looping construct specifically designed to iterate while a condition is true, at the same time offering a stepping mechanism (generally to increase the iterator). Example:
for (var i=0, n=arr.length; i < n; ++i ) {
...
}
This isn't to suggest that for-loops will always be more efficient, just that JS engines and browsers have optimized them to be so. Over the years there have been compromises as to which looping construct is more efficient (for, while, reduce, reverse-while, etc) -- different browsers and JS engines have their own implementations that offer different methodologies to produce the same results. As browsers further optimize to meet performance demands, theoretically [].forEach
could be implemented in such a way that it's faster or comparable to a for
.
Benefits:
- efficient
- early loop termination (honors
break
andcontinue
) - condition control (
i<n
can be anything and not bound to an array's size) - variable scoping (
var i
leavesi
available after the loop ends)
forEach
.forEach
are methods that primarily iterate over arrays (also over other enumerable, such as Map
and Set
objects). They are newer and provide code that is subjectively easier to read. Example:
[].forEach((val, index)=>{
...
});
Benefits:
- does not involve variable setup (iterates over each element of the array)
- functions/arrow-functions scope the variable to the block
In the example above,val
would be a parameter of the newly created function. Thus, any variables calledval
before the loop, would hold their values after it ends. - subjectively more maintainable as it may be easier to identify what the code is doing -- it's iterating over an enumerable; whereas a for-loop could be used for any number of looping schemes
Performance
Performance is a tricky topic, which generally requires some experience when it comes to forethought or approach. In order to determine ahead of time (while developing) how much optimization may be required, a programmer must have a good idea of past experience with the problem case, as well as a good understanding of potential solutions.
Using jQuery in some cases may be too slow at times (an experienced developer may know that), whereas other times may be a non-issue, in which case the library's cross-browser compliance and ease of performing other functions (e.g., AJAX, event-handling) would be worth the development (and maintenance) time saved.
Another example is, if performance and optimization was everything, there would be no other code than machine or assembly. Obviously that isn't the case as there are many different high level and low level languages, each with their own tradeoffs. These tradeoffs include, but are not limited to specialization, development ease and speed, maintenance ease and speed, optimized code, error free code, etc.
Approach
If you don't have a good understanding if something will require optimized code, it's generally a good rule of thumb to write maintainable code first. From there, you can test and pinpoint what needs more attention when it's required.
That said, certain obvious optimizations should be part of general practice and not required any thought. For instance, consider the following loop:
for (var i=0; i < arr.length; ++i ){}
For each iteration of the loop, JavaScript is retrieving the arr.length
, a key-lookup costing operations on each cycle. There is no reason why this shouldn't be:
for (var i=0, n=arr.length; i < n; ++i){}
This does the same thing, but only retrieves arr.length
once, caching the variable and optimizing your code.
for loop vs while loop vs foreach loop PHP
which one is better for performance?
It doesn't matter.
what's the criteria to select a loop?
If you just need to walk through all the elements of an object or array, use foreach
. Cases where you need for
include
- When you explicitly need to do things with the numeric index, for example:
- when you need to use previous or next elements from within an iteration
- when you need to change the counter during an iteration
foreach
is much more convenient because it doesn't require you to set up the counting, and can work its way through any kind of member - be it object properties or associative array elements (which a for
won't catch). It's usually best for readability.
which should be used when we loop inside another loop?
Both are fine; in your demo case, foreach
is the simplest way to go.
Performance difference for control structures 'for' and 'foreach' in C#
Well, it partly depends on the exact type of list
. It will also depend on the exact CLR you're using.
Whether it's in any way significant or not will depend on whether you're doing any real work in the loop. In almost all cases, the difference to performance won't be significant, but the difference to readability favours the foreach
loop.
I'd personally use LINQ to avoid the "if" too:
foreach (var item in list.Where(condition))
{
}
EDIT: For those of you who are claiming that iterating over a List<T>
with foreach
produces the same code as the for
loop, here's evidence that it doesn't:
static void IterateOverList(List<object> list)
{
foreach (object o in list)
{
Console.WriteLine(o);
}
}
Produces IL of:
.method private hidebysig static void IterateOverList(class [mscorlib]System.Collections.Generic.List`1<object> list) cil managed
{
// Code size 49 (0x31)
.maxstack 1
.locals init (object V_0,
valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object> V_1)
IL_0000: ldarg.0
IL_0001: callvirt instance valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<!0> class [mscorlib]System.Collections.Generic.List`1<object>::GetEnumerator()
IL_0006: stloc.1
.try
{
IL_0007: br.s IL_0017
IL_0009: ldloca.s V_1
IL_000b: call instance !0 valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>::get_Current()
IL_0010: stloc.0
IL_0011: ldloc.0
IL_0012: call void [mscorlib]System.Console::WriteLine(object)
IL_0017: ldloca.s V_1
IL_0019: call instance bool valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>::MoveNext()
IL_001e: brtrue.s IL_0009
IL_0020: leave.s IL_0030
} // end .try
finally
{
IL_0022: ldloca.s V_1
IL_0024: constrained. valuetype [mscorlib]System.Collections.Generic.List`1/Enumerator<object>
IL_002a: callvirt instance void [mscorlib]System.IDisposable::Dispose()
IL_002f: endfinally
} // end handler
IL_0030: ret
} // end of method Test::IterateOverList
The compiler treats arrays differently, converting a foreach
loop basically to a for
loop, but not List<T>
. Here's the equivalent code for an array:
static void IterateOverArray(object[] array)
{
foreach (object o in array)
{
Console.WriteLine(o);
}
}
// Compiles into...
.method private hidebysig static void IterateOverArray(object[] 'array') cil managed
{
// Code size 27 (0x1b)
.maxstack 2
.locals init (object V_0,
object[] V_1,
int32 V_2)
IL_0000: ldarg.0
IL_0001: stloc.1
IL_0002: ldc.i4.0
IL_0003: stloc.2
IL_0004: br.s IL_0014
IL_0006: ldloc.1
IL_0007: ldloc.2
IL_0008: ldelem.ref
IL_0009: stloc.0
IL_000a: ldloc.0
IL_000b: call void [mscorlib]System.Console::WriteLine(object)
IL_0010: ldloc.2
IL_0011: ldc.i4.1
IL_0012: add
IL_0013: stloc.2
IL_0014: ldloc.2
IL_0015: ldloc.1
IL_0016: ldlen
IL_0017: conv.i4
IL_0018: blt.s IL_0006
IL_001a: ret
} // end of method Test::IterateOverArray
Interestingly, I can't find this documented in the C# 3 spec anywhere...
Related Topics
How to Resolve a Java Rounding Double Issue
Centering a Jlabel on a JPAnel
Converting Array to List in Java
Hibernate Annotations - Which Is Better, Field or Property Access
Why Is There No Multiple Inheritance in Java, But Implementing Multiple Interfaces Is Allowed
Spring Boot and Multiple External Configuration Files
What Does the Java Assert Keyword Do, and When Should It Be Used
Why Should I Use the Keyword "Final" on a Method Parameter in Java
How to Share Data with Two(2) Swingworker Class in Java
Splitting a String at Every N-Th Character
Java Event-Dispatching Thread Explanation
What Is an Outofmemoryerror and How to Debug and Fix It
What Is the "Execute Around" Idiom