How is Java's for loop code generated by the compiler?
For example, if I have:
for(String s : getStringArray() )
{
//do something with s
}
where getStringArray()
is a function that returns the Array I want to loop on, would function be called always or only once? How optimal is the code for looping using this construct in general?
for
loopHere is the relevant excerpts from the Java Language Specification 3rd Edition, slightly edited for clarity:
JLS 14.14.2 The enhanced
for
statementThe enhanced
for
statement has the form:for ( Type Identifier : Expression ) Statement
If the type of
Expression
is an array type,T[]
, then the meaning of the enhancedfor
statement is given by the following basicfor
statement:T[] a = Expression; for (int i = 0; i < a.length; i++) { Type Identifier = a[i]; Statement }
where
a
andi
are compiler-generated identifiers that are distinct from any other identifiers (compiler-generated or otherwise) that are in scope at the point where the enhancedfor
statement occurs.
So in fact the language does guarantee that Expression
will only be evaluated once.
For completeness, here's the equivalence when the Expression
is of type Iterable
:
JLS 14.14.2 The enhanced
for
statementThe enhanced
for
statement has the form:for ( Type Identifier : Expression ) Statement
If the type of
Expression
is a subtype ofIterable
, then letI
be the type of the expressionExpression.iterator()
. The enhancedfor
statement is equivalent to a basicfor
statement of the form:for (I iter = Expression.iterator(); iter.hasNext(); ) { Type Identifier = iter.next(); Statement }
where
iter
is a compiler-generated identifier that is distinct from any other identifiers (compiler-generated or otherwise) that are in scope at the point where the enhancedfor
statement occurs.
Note that it is a compile-time error if Expression
is neither an Iterable
nor an array, so the above two are the only cases where you can use an enhanced for
loop. Also, for clarity, the above quotes leave out information regarding any labels attached on the for
loop and any modifiers attached on the Identifier
, but these are handled as one would expect.
for
loopHere's a quote from Effective Java 2nd Edition, Item 46: Prefer for-each loops to traditional for loops
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. 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, programmers don't always do so.
Thus the book claims that in fact some compilers go beyond the JLS translation and performs additional optimization on the for-each loop (while still maintaining its semantics, of course).
In summary, you should not worry about the performance of for-each loop. The specification by the language is sensible (Expression
only evaluated once), and precisely because this is the preferred construct in many scenarios, compilers will make sure to optimize them as best they can.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With