Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java for-each on getter

If javac do what I think, the following lines would yield the same performance:

for (Object o: getObjects()) {}
List<Object> os = getObjects(); for (Object o: os) {}

Is it so or not? Or is it perhaps implementation-specific? If so: anybody know about GWT?

like image 518
Jonas Byström Avatar asked Jun 04 '10 12:06

Jonas Byström


3 Answers

The performance will be identical.

The Java compiler turns for-each loops into a loop around an Iterator object by calling the iterator() method on the object that you loop over.
Therefore, the actual list instance is only used once. (To call iterator())

like image 74
SLaks Avatar answered Nov 10 '22 13:11

SLaks


From the Java Language Specifications:

14.14.2 The enhanced for statement

The enhanced for statement has the form:

EnhancedForStatement:
        for ( VariableModifiersopt Type Identifier: Expression) Statement

The Expression must either have type Iterable or else it must be of an array type (§10.1), or a compile-time error occurs.

The scope of a local variable declared in the FormalParameter part of an enhanced for statement (§14.14) is the contained Statement

The meaning of the enhanced for statement is given by translation into a basic for statement.

If the type of Expression is a subtype of Iterable, then let I be the type of the expression Expression.iterator(). The enhanced for statement is equivalent to a basic for statement of the form:

for (I #i = Expression.iterator(); #i.hasNext(); ) {

        VariableModifiersopt Type Identifier = #i.next();
   Statement
}

Where #i is a compiler-generated identifier that is distinct from any other identifiers (compiler-generated or otherwise) that are in scope (§6.3) at the point where the enhanced for statement occurs.

As you can see, Expression is mentioned only in the first part of the for loop expression and is thus only evaluated once. So your two lines would yield the same performance.

like image 28
Pascal Thivent Avatar answered Nov 10 '22 15:11

Pascal Thivent


These answers all seem correct from a pure Java perspective. Furthermore, if it can, the GWT compiler will actually rewrite the enhanced for loop further, into a regular for loop before it generates the JavaScript. So it will actually end up looking something like:

for (int i = 0; i < getObjects().size(); i++) {
  Object o = getObjects().get(i);
  // ...
}

The reason? If the List iterator object is never referenced, it can be declared as dead code and won't be rewritten in JavaScript, resulting in a smaller download size. This optimization should have no effect whatsoever on the actual execution of your code.

See Optimizing apps with the GWT compiler, from this year's Google I/O, for more details about other crazy things the GWT compiler does to reduce JS size.

like image 5
Jason Hall Avatar answered Nov 10 '22 14:11

Jason Hall