0

I've using the "foreach" loop in my Java applications for a long time. Recently I started wondering if there is any significative difference in performance (or even in the result) between:

Collection<String> collection = someMethod();
for(String element : collection) { ... }

and:

for(String element : someMethod()) { ... }

What if instead of a Collection it is a List, a Map, a Set or an array?

10
  • 1
    Why would you suspect a performance difference? Commented May 6, 2014 at 12:13
  • How did you find the difference in performance? Commented May 6, 2014 at 12:14
  • possible duplicate of Is there a performance difference between a for loop and a for-each loop? Commented May 6, 2014 at 12:15
  • 1
    I'd prefer the former. If you are wondering if someMethod() is called multiple times (it shouldn't be), put a debug statement in there. Commented May 6, 2014 at 12:17
  • 1
    I think he was being afraid that someMethod() will be called multiple times(more exactly: for each iteration) , resulting into a tiny-to-huge performance difference, depending on what someMethod() is doing. I think it is a duplicate of : stackoverflow.com/questions/3298202/… Commented May 6, 2014 at 13:27

4 Answers 4

3

The difference between both codes can be seen in their generated bytecodes.

The first one has extra two instructions over the second one; it stores the return value of someMethod() on the local stack and then loads it again for accessing it's iterator.

However the second one immediately uses the Iterator without storing the return value of someMethod() on the local stack.

Below code shows the elimination of 3: and 4: instructions.

First:

Collection<String> collection = someMethod();
for(String element : collection) { ... }

     0: invokestatic  #3                  // Call someMethod()
     3: astore_1                          // Store the result as first item on local stack
     4: aload_1                           // Load the Collection again into operand stack
     5: invokeinterface #4,  1            // Get Iterator (of Collection) - InterfaceMethod java/util/Collection.iterator:()Ljava/util/Iterator;
    10: astore_2                          // Store Iterator on local stack #2
    11: aload_2                           // LOOP STARTS - Load iterator
    12: invokeinterface #5,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
    17: ifeq          33
    20: aload_2       
    21: invokeinterface #6,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    26: checkcast     #7                  // class java/lang/String
    29: astore_3      
    30: goto          11                  // LOOP ENDS
    33: return

Second

for(String element : someMethod()) { ... }

     0: invokestatic  #3                  // Call someMethod() 
     3: invokeinterface #4,  1            // Get Iterator (of Collection) - Interface Method java/util/Collection.iterator:()Ljava/util/Iterator;/
     8: astore_1                          // Store Iterator on local stack #2  
     9: aload_1                           // LOOP STARTS - Load iterator
    10: invokeinterface #5,  1            // InterfaceMethod java/util/Iterator.hasNext:()Z
    15: ifeq          31
    18: aload_1       
    19: invokeinterface #6,  1            // InterfaceMethod java/util/Iterator.next:()Ljava/lang/Object;
    24: checkcast     #7                  // class java/lang/String
    27: astore_2      
    28: goto          9                   // LOOP ENDS
    31: return       

BTW, I don't think that they will have a big difference in terms of performance since both have 9 instructions inside the loop.

Sign up to request clarification or add additional context in comments.

Comments

2

There is no visible performance difference between the two. The first way is more elegant and readable than the second one. But from performance point of view its not a deterrent. Both produce identical bytecode for the 'inside the loop' part.

Comments

1

It's a semantic difference, you won't see any real performance change in your code as a result of assigning a method return value to a local variable. Lists, Sets, Map entry sets, arrays are all iterable in the for-each loop, so they are all fine and result in you not having to know the return collection type.

Comments

1

For compatibility you shall use the second and if you know the result is never null.

The first shall not be used if you dont need the collection anymore.

I prefer a third suggestion:

Collection<String> collection = someMethod();
if (collection != null) {
    for(String element : collection) { ... }
}

Regards.

3 Comments

I usually prefer to return an empty collection if someMethod() is written by me and not part of some 3rd party library, just to avoid these annoying checkings against null.
I really like you to be my collegue. Can i ask you something? how do you think about assert collection != null;?
I think it is a really bad idea to use assertion in these situations(before iterating over a collection) because I would not like my program to terminate if the collection is null. IMHO assertions have their place in testing , not in production code, but again: this is only my humble opinion .

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.