views:

932

answers:

6

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.

+18  A: 

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
It won't use an iterator for an array.
Jon Skeet
the first style is limited to Integer.MAX number of iterations, while the second one is not.
Chii
The second is also limited that way because arrays have a max Integer.MAX_VALUE number of elements and an ArrayList is backed by an array.
cletus
+4  A: 

This has been asked before.

RichardOD
+6  A: 

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
A: 

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.

jgubby
+11  A: 

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
A: 

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

kd304