37

In Java, is it faster to iterate through an array the old-fashioned way,

for (int i = 0; i < a.length; i++)
    f(a[i]);

Or using the more concise form,

for (Foo foo : a)
    f(foo);

For an ArrayList, is the answer the same?

Of course for the vast bulk of application code, the answer is it makes no discernible difference so the more concise form should be used for readability. However the context I'm looking at is heavy duty technical computation, with operations that must be performed billions of times, so even a tiny speed difference could end up being significant.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
rwallace
  • 31,405
  • 40
  • 123
  • 242
  • Why not run a benchmark? Much more accurate than a discussion. – Deestan Sep 03 '12 at 12:21
  • You are unlikely to notice the difference unless `f()` is vanishingly short. – user207421 Dec 30 '13 at 03:51
  • This has been [asked before](http://stackoverflow.com/questions/256859/is-there-a-performance-difference-between-a-for-loop-and-a-for-each-loop). – RichardOD Jun 17 '09 at 11:12
  • That's not an array. In the "asked before question" internally an iterator will be created with the foreach loop, whereas here it won't according to the answers here. – Albert Hendriks Mar 01 '13 at 09:54
  • Technically this is indeed a different question. There is a difference between an array and a list. As such the technical implementation is different and might lead to different results. The answer of Jon Skeet is nice for the array. – Gunnar Bernstein Aug 15 '19 at 12:47

6 Answers6

68

If you're looping through an array, it shouldn't matter - the enhanced for loop uses array accesses anyway.

For example, consider this code:

public static void main(String[] args)
{
    for (String x : args)
    {
        System.out.println(x);
    }
}

When decompiled with javap -c Test we get (for the main method):

public static void main(java.lang.String[]);
  Code:
   0:   aload_0
   1:   astore_1
   2:   aload_1
   3:   arraylength
   4:   istore_2
   5:   iconst_0
   6:   istore_3
   7:   iload_3
   8:   iload_2
   9:   if_icmpge   31
   12:  aload_1
   13:  iload_3
   14:  aaload
   15:  astore  4
   17:  getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   20:  aload   4
   22:  invokevirtual   #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   25:  iinc    3, 1
   28:  goto    7
   31:  return

Now change it to use an explicit array access:

public static void main(String[] args)
{
    for (int i = 0; i < args.length; i++)
    {
        System.out.println(args[i]);
    }
}

This decompiles to:

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iload_1
   3:   aload_0
   4:   arraylength
   5:   if_icmpge   23
   8:   getstatic   #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   11:  aload_0
   12:  iload_1
   13:  aaload
   14:  invokevirtual   #3; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   17:  iinc    1, 1
   20:  goto    2
   23:  return

There's a bit more setup code in the enhanced for loop, but they're basically doing the same thing. No iterators are involved. Furthermore, I'd expect them to get JITted to even more similar code.

Suggestion: if you really think it might make a significant difference (which it would only ever do if the body of the loop is absolutely miniscule) then you should benchmark it with your real application. That's the only situation which matters.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
23

This falls squarely in the arena of micro-optimization. It really doesn't matter. Stylistically I always prefer the second because it's more concise, unless you need the loop counter for something else. And that's far more important than this kind of micro-optimization: readability.

That being said, For an ArrayList there won't be much difference but a LinkedList will be much more efficient with the second.

cletus
  • 616,129
  • 168
  • 910
  • 942
8

Measure it. The answer on all performance-questions can depend on VM-version, processor, memory-speed, caches etc. So you have to measure it for your particular platform.

Personally I would prefer the second variant, because the intention is more clear. If performance becomes a problem I can optimize it later anyways - if that code really is important for the performance of the whole application.

Mnementh
  • 50,487
  • 48
  • 148
  • 202
2

For a LinkedList:

for(ClassOfElement element : listOfElements) {
  System.out.println(element.getValue());
}

It was answered before:

Is there a performance difference between a for loop and a for-each loop?

Community
  • 1
  • 1
David García González
  • 5,164
  • 8
  • 29
  • 35
1

On an array, or RandomAccess collection you can get a tiny increase in speed by doing:

List<Object> list = new ArrayList<Object>();

for (int i=0, d=list.size(); i<d; i++) {
    something(list.get(i));
}

But I wouldn't worry in general. Optimisations like this wont make more than 0.1% difference to your code. Try invoking java with -prof to see where your code is actually spending its time.

gub
  • 5,079
  • 3
  • 28
  • 33
1

Even faster is to use the ParallelArray of the fork-join framework (if you have large enough dataset).

akarnokd
  • 69,132
  • 14
  • 157
  • 192