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

What, if any, is the performance difference between the following two loops?

for (Object o: objectArrayList) {
    o.DoSomething();
}

and

for (int i=0; i<objectArrayList.size(); i++) {
    objectArrayList.get(i).DoSomething();
}


Asked by: Stuart822 | Posted: 21-01-2022






Answer 1

From Item 46 in Effective Java by Joshua Bloch :

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:

// The preferred idiom for iterating over collections and arrays
for (Element e : elements) {
    doSomething(e);
}

When you see the colon (:), read it as “in.” Thus, the loop above reads as “for each element e in elements.” 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 (Item 45), programmers don’t always do so.

Answered by: Catherine335 | Posted: 22-02-2022



Answer 2

All these loops do the exact same, I just want to show these before throwing in my two cents.

First, the classic way of looping through List:

for (int i=0; i < strings.size(); i++) { /* do something using strings.get(i) */ }

Second, the preferred way since it's less error prone (how many times have YOU done the "oops, mixed the variables i and j in these loops within loops" thing?).

for (String s : strings) { /* do something using s */ }

Third, the micro-optimized for loop:

int size = strings.size();
for (int i = -1; ++i < size;) { /* do something using strings.get(i) */ }

Now the actual two cents: At least when I was testing these, the third one was the fastest when counting milliseconds on how long it took for each type of loop with a simple operation in it repeated a few million times - this was using Java 5 with jre1.6u10 on Windows in case anyone is interested.

While it at least seems to be so that the third one is the fastest, you really should ask yourself if you want to take the risk of implementing this peephole optimization everywhere in your looping code since from what I've seen, actual looping isn't usually the most time consuming part of any real program (or maybe I'm just working on the wrong field, who knows). And also like I mentioned in the pretext for the Java for-each loop (some refer to it as Iterator loop and others as for-in loop) you are less likely to hit that one particular stupid bug when using it. And before debating how this even can even be faster than the other ones, remember that javac doesn't optimize bytecode at all (well, nearly at all anyway), it just compiles it.

If you're into micro-optimization though and/or your software uses lots of recursive loops and such then you may be interested in the third loop type. Just remember to benchmark your software well both before and after changing the for loops you have to this odd, micro-optimized one.

Answered by: Agata800 | Posted: 22-02-2022



Answer 3

Well, performance impact is mostly insignificant, but isn't zero. If you look at JavaDoc of RandomAccess interface:

As a rule of thumb, a List implementation should implement this interface if, for typical instances of the class, this loop:

for (int i=0, n=list.size(); i < n; i++)
    list.get(i);

runs faster than this loop:

for (Iterator i=list.iterator(); i.hasNext();)
      i.next();

And for-each loop is using version with iterator, so for ArrayList for example, for-each loop isn't fastest.

Answered by: David516 | Posted: 22-02-2022



Answer 4

The for-each loop should generally be preferred. The "get" approach may be slower if the List implementation you are using does not support random access. For example, if a LinkedList is used, you would incur a traversal cost, whereas the for-each approach uses an iterator that keeps track of its position in the list. More information on the nuances of the for-each loop.

I think the article is now here: new location

The link shown here was dead.

Answered by: Lucas142 | Posted: 22-02-2022



Answer 5

There appears to be a difference unfortunately.

If you look at the generated bytes code for both kinds of loops, they are different.

Here is an example from the Log4j source code.

In /log4j-api/src/main/java/org/apache/logging/log4j/MarkerManager.java we have a static inner class called Log4jMarker which defines:

    /*
     * Called from add while synchronized.
     */
    private static boolean contains(final Marker parent, final Marker... localParents) {
        //noinspection ForLoopReplaceableByForEach
        for (final Marker marker : localParents) {
            if (marker == parent) {
                return true;
            }
        }
        return false;
    }

With standard loop:

  private static boolean contains(org.apache.logging.log4j.Marker, org.apache.logging.log4j.Marker...);
    Code:
       0: iconst_0
       1: istore_2
       2: aload_1
       3: arraylength
       4: istore_3
       5: iload_2
       6: iload_3
       7: if_icmpge     29
      10: aload_1
      11: iload_2
      12: aaload
      13: astore        4
      15: aload         4
      17: aload_0
      18: if_acmpne     23
      21: iconst_1
      22: ireturn
      23: iinc          2, 1
      26: goto          5
      29: iconst_0
      30: ireturn

With for-each:

  private static boolean contains(org.apache.logging.log4j.Marker, org.apache.logging.log4j.Marker...);
    Code:
       0: aload_1
       1: astore_2
       2: aload_2
       3: arraylength
       4: istore_3
       5: iconst_0
       6: istore        4
       8: iload         4
      10: iload_3
      11: if_icmpge     34
      14: aload_2
      15: iload         4
      17: aaload
      18: astore        5
      20: aload         5
      22: aload_0
      23: if_acmpne     28
      26: iconst_1
      27: ireturn
      28: iinc          4, 1
      31: goto          8
      34: iconst_0
      35: ireturn

What is up with THAT Oracle?

I've tried this with Java 7 and 8 on Windows 7.

Answered by: Max341 | Posted: 22-02-2022



Answer 6

foreach makes the intention of your code clearer and that is normally preferred over a very minor speed improvement - if any.

Whenever I see an indexed loop I have to parse it a little longer to make sure it does what I think it does E.g. Does it start from zero, does it include or exclude the end point etc.?

Most of my time seems to be spent reading code (that I wrote or someone else wrote) and clarity is almost always more important than performance. Its easy to dismiss performance these days because Hotspot does such an amazing job.

Answered by: Walter444 | Posted: 22-02-2022



Answer 7

The following code:

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;

interface Function<T> {
    long perform(T parameter, long x);
}

class MyArray<T> {

    T[] array;
    long x;

    public MyArray(int size, Class<T> type, long x) {
        array = (T[]) Array.newInstance(type, size);
        this.x = x;
    }

    public void forEach(Function<T> function) {
        for (T element : array) {
            x = function.perform(element, x);
        }
    }
}

class Compute {
    int factor;
    final long constant;

    public Compute(int factor, long constant) {
        this.factor = factor;
        this.constant = constant;
    }

    public long compute(long parameter, long x) {
        return x * factor + parameter + constant;
    }
}

public class Main {

    public static void main(String[] args) {
        List<Long> numbers = new ArrayList<Long>(50000000);
        for (int i = 0; i < 50000000; i++) {
            numbers.add(i * i + 5L);
        }

        long x = 234553523525L;

        long time = System.currentTimeMillis();
        for (int i = 0; i < numbers.size(); i++) {
            x += x * 7 + numbers.get(i) + 3;
        }
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(x);
        x = 0;
        time = System.currentTimeMillis();
        for (long i : numbers) {
            x += x * 7 + i + 3;
        }
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(x);
        x = 0;
        numbers = null;
        MyArray<Long> myArray = new MyArray<Long>(50000000, Long.class, 234553523525L);
        for (int i = 0; i < 50000000; i++) {
            myArray.array[i] = i * i + 3L;
        }
        time = System.currentTimeMillis();
        myArray.forEach(new Function<Long>() {

            public long perform(Long parameter, long x) {
                return x * 8 + parameter + 5L;
            }
        });
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(myArray.x);
        myArray = null;
        myArray = new MyArray<Long>(50000000, Long.class, 234553523525L);
        for (int i = 0; i < 50000000; i++) {
            myArray.array[i] = i * i + 3L;
        }
        time = System.currentTimeMillis();
        myArray.forEach(new Function<Long>() {

            public long perform(Long parameter, long x) {
                return new Compute(8, 5).compute(parameter, x);
            }
        });
        System.out.println(System.currentTimeMillis() - time);
        System.out.println(myArray.x);
    }
}

Gives following output on my system:

224
-699150247503735895
221
-699150247503735895
220
-699150247503735895
219
-699150247503735895

I'm running Ubuntu 12.10 alpha with OracleJDK 1.7 update 6.

In general HotSpot optimizes a lot of indirections and simple reduntant operations, so in general you shouldn't worry about them unless there are a lot of them in seqence or they are heavily nested.

On the other hand, indexed get on LinkedList is much slower than calling next on iterator for LinkedList so you can avoid that performance hit while retaining readability when you use iterators (explicitly or implicitly in for-each loop).

Answered by: Kelvin917 | Posted: 22-02-2022



Answer 8

Here is a brief analysis of the difference put out by the Android development team:

https://www.youtube.com/watch?v=MZOf3pOAM6A

The result is that there is a difference, and in very restrained environments with very large lists it could be a noticeable difference. In their testing, the for each loop took twice as long. However, their testing was over an arraylist of 400,000 integers. The actual difference per element in the array was 6 microseconds. I haven't tested and they didn't say, but I would expect the difference to be slightly larger using objects rather than primitives, but even still unless you are building library code where you have no idea the scale of what you will be asked to iterate over, I think the difference is not worth stressing about.

Answered by: Kellan167 | Posted: 22-02-2022



Answer 9

The only way to know for sure is to benchmark it, and even that is not as simple as it may sound. The JIT compiler can do very unexpected things to your code.

Answered by: Chloe969 | Posted: 22-02-2022



Answer 10

Even with something like an ArrayList or Vector, where "get" is a simple array lookup, the second loop still has additional overhead that the first one doesn't. I would expect it to be a tiny bit slower than the first.

Answered by: Julian169 | Posted: 22-02-2022



Answer 11

By the variable name objectArrayList, I assume that is an instance of java.util.ArrayList. In that case, the performance difference would be unnoticeable.

On the other hand, if it's an instance of java.util.LinkedList, the second approach will be much slower as the List#get(int) is an O(n) operation.

So the first approach is always preferred unless the index is needed by the logic in the loop.

Answered by: Marcus514 | Posted: 22-02-2022



Answer 12

Seems to me like the other answers are based on the incorrect benchmarks, that doesn't take Hotspot's compilation and optimization process into an account.

Short answer

Use enhanced-loop when possible, because most of the time it's the fastest. If you cannot, pull the entire array into a local variable if possible:

int localArray = this.array;
for (int i = 0; i < localArray.length; i++) { 
    methodCall(localArray[i]); 
}

Long answer

Now, usually there is no difference, because Hotspot is very good at optimizing and getting rid of checks that java needs to do.

But sometimes some optimizations just cannot be done, usually because you have a virtual call inside a loop, that cannot be inlined. In that case, some loops can really be faster than others.

Few of the things that Java needs to do:

  • reload this.array - because it could be changed (by the call or another thread)
  • check whether i is in inside the bounds of the array, if not throw IndexOutOfBoundsException
  • check whether an accessed object reference is null, if yes throw NullPointerException

Consider this c-style loop:

for (int i = 0; i < this.array.length; i++) { //now java knows i < this.array.length
    methodCall(this.array[i]);// no need to check
}

By evaluating the loop condition i < this.array.length, java knows that i must be inside of bounds (i is changed only after the call), so don't need to check it again in the next line. But in this case java needs to reload this.array.length.

You might be tempted to "optimize" the loop, by pulling the this.array.length value inside of the local variable:

int len = this.array.length;//len is now a local variable
for (int i = 0; i < len; i++) { //no reload needed
    methodCall(this.array[i]); //now java will do the check
}

Now java don't need to reload every single time, because a local variable can be cannot be changed by the methodCall and/or another thread. Local variables can be changed only inside the method itself, and java now can prove that variable len could not change.

But now the loop condition i < this.array.length changed to i < len, and previous optimization fails, and java need to check whether the i in inside of bounds of this.array.

A better optimization would be to pull entire array into a local variable:

ArrayType[] localArray = this.array;
for (int i = 0; i < localArray.length; i++) { 
    methodCall(localArray[i]); 
}

Now java don't need to reload the array, and the "i in bounds" check is also eliminated.

And what about the enhanced-loop? Well, usually the compiler rewrites your enhanced loop into something like the last shown loop, if not even better.

Answered by: Owen192 | Posted: 22-02-2022



Answer 13

It's weird that no one has mentioned the obvious - foreach allocates memory (in the form of an iterator), whereas a normal for loop does not allocate any memory. For games on Android, this is a problem, because it means that the garbage collector will run periodically. In a game you don't want the garbage collector to run... EVER. So don't use foreach loops in your draw (or render) method.

Answered by: Caroline559 | Posted: 22-02-2022



Answer 14

It's always better to use the iterator instead of indexing. This is because iterator is most likely optimzied for the List implementation while indexed (calling get) might not be. For example LinkedList is a List but indexing through its elements will be slower than iterating using the iterator.

Answered by: Elise728 | Posted: 22-02-2022



Answer 15

1. for(Object o: objectArrayList){
    o.DoSomthing();
}
and

2. for(int i=0; i<objectArrayList.size(); i++){
    objectArrayList.get(i).DoSomthing();
}

Both does the same but for easy and safe programming use for-each, there are possibilities for error prone in 2nd way of using.

Answered by: Edgar151 | Posted: 22-02-2022



Answer 16

Accepted answer answers the question, apart from the exceptional case of ArrayList...

Since most developers rely on ArrayList(atleast I believe so)

So I am obligated to add the correct answer here.

Straight from the developer documentation:-

The enhanced for loop (also sometimes known as "for-each" loop) can be used for collections that implement the Iterable interface and for arrays. With collections, an iterator is allocated to make interface calls to hasNext() and next(). With an ArrayList, a hand-written counted loop is about 3x faster (with or without JIT), but for other collections the enhanced for loop syntax will be exactly equivalent to explicit iterator usage.

There are several alternatives for iterating through an array:

static class Foo {
    int mSplat;
}

Foo[] mArray = ...

public void zero() {
    int sum = 0;
    for (int i = 0; i < mArray.length; ++i) {
        sum += mArray[i].mSplat;
    }
}

public void one() {
    int sum = 0;
    Foo[] localArray = mArray;
    int len = localArray.length;

    for (int i = 0; i < len; ++i) {
        sum += localArray[i].mSplat;
    }
}

public void two() {
    int sum = 0;
    for (Foo a : mArray) {
        sum += a.mSplat;
    }
}

zero() is slowest, because the JIT can't yet optimize away the cost of getting the array length once for every iteration through the loop.

one() is faster. It pulls everything out into local variables, avoiding the lookups. Only the array length offers a performance benefit.

two() is fastest for devices without a JIT, and indistinguishable from one() for devices with a JIT. It uses the enhanced for loop syntax introduced in version 1.5 of the Java programming language.

So, you should use the enhanced for loop by default, but consider a hand-written counted loop for performance-critical ArrayList iteration.

Answered by: Walter516 | Posted: 22-02-2022



Similar questions

java - Is there a performance difference between Javac debug on and off?

If I switch on the generating of debug info with Javac then the class files are 20-25% larger. Has this any performance effects on running the Java program? If yes on which conditions and how many. I expect a little impact on loading the classes because the files are larger but this should be minimal.


java - Performance difference between annotating fields or getter methods in Hibernate / JPA

I was curious if anyone had any hard numbers around the performance difference between annotating Entities using private fields instead of public getter methods. I've heard people say that fields are slower because they're called "through reflection" but then again so are the getter methods, no? Hibernate needs to set the accessibility of the field to true before it tries to read it which I can see having some slight...


Vast difference in Java Performance from 1.4 to 1.6

I have observed a great difference in Sun Java performance when code is compiled through jdk1.6 as compared to jdk1.5 or jdk1.4 (over 4 folds) What changes and optimizations have been done? Is there anything worth taking home from these changes which will help to boost our application performance. Thanks for replying


java - Is there a performance difference between these two pieces of code?

Is there a performance difference between these two pieces of code? My gut feeling is that the second option is slower, as the Cell object has to be constructed each time, but I like the idea of returning a Cell. Option One: //Call to method initiTextDefaultCell(borders); iTextTable.setDefaultCell(iTextDefaultCell); //Other code... private void initiTextDefaultCell(boolean borders) { if (!border...


Java for loop vs. while loop. Performance difference?

Assume i have the following code, there are three for loop to do something. Would it run fast if i change the most outer for loop to while loop? thanks~~ int length = 200; int test = 0; int[] input = new int[10]; for(int i = 1; i &lt;= length; i++) { for (int j = 0; j &lt;=length - i; j++) { for (int k = 0; k &lt; length - 1; k++) { test = test + input[j + k]; } ...


What is the performance difference, if any, between if(!foo) and if(foo == false) in Java?

Logically, if(!foo) and if(foo == false) are equivalent. How are they represented in Java? Is there any difference between the two after compilation, either in the bytecode or in performance? I was unable to find an answer in the JLS, and searching brought up a lot of results about = vs. == typos and ==/equals() behavior. (In this case, the symbols hampered my searching; for future searchers, ...


java - Difference in performance between Stax and DOM parsing

I have been using DOM for a long time and as such DOM parsing performance wise has been pretty good. Even when dealing with XML of about 4-7 MB the parsing has been fast. The issue we face with DOM is the memory footprint which become huge as soon as we start dealing with large XMLs. Lately I tried moving to Stax (Streaming parsers for XML) which are supposed top be second generation parsers (reading about Stax it ...


java - Performance difference between Iterator Class and foreach construct

I have the following code running, but I sometimes get some sort of concurrency exception when running it. ArrayList&lt;Mob&gt; carriers = new ArrayList&lt;Mob&gt;(); ArrayList&lt;Mob&gt; mobs = new ArrayList&lt;Mob&gt;(); ... for (Mob carrier : carriers){ for (Mob mob : mobs){ checkInfections (carrier, mob); } } I refactored it to solve the concurrency problem, but it did...


java - Is there a performance difference between using 20 jars and using only one repacking them?

My program uses around 20 jars (for a total size of about 30mb). For now, they are all added to the classpath for the released version, and all jars are deployed with the rest. Would there be a performance impact if I was unpacking them and repacking them into one jar?


java - Performance difference of Native SQL(using MySQL) vs using Hibernate ORM?

I am using Spring MVC for an application that involved a multilevel back end for management and a customer/member front end. The project was initially started with no framework and simple native JDBC calls for database access. As the project has grown significantly(as they always do) I have made more significant database calls, sometimes querying large selection sizes. I am doing what I can to treat my db c...


Performance question: Fastest way to convert hexadecimal char to its number value in Java?

I want to convert from char representing a hexadecimal value (in upper or lower case) to byte, like '0'-&gt;0, '1' -&gt; 1, 'A' -&gt; 10, 'a' -&gt; 10, 'f' -&gt; 15 etc... I will be calling this method extremely often, so performance is important. Is there a faster way than to use a pre-initialized HashMap&lt;Character,Byte&gt; to get the value from? Answer


performance - Java very large heap sizes

Closed. This question needs to be more focused. It ...


java - Is there a performance difference between Javac debug on and off?

If I switch on the generating of debug info with Javac then the class files are 20-25% larger. Has this any performance effects on running the Java program? If yes on which conditions and how many. I expect a little impact on loading the classes because the files are larger but this should be minimal.


performance - Size of a byte in memory - Java

I have heard mixed opinions over the amount of memory that a byte takes up in a java program. I am aware you can store no more than +127 in a java byte, and the documentation says that a byte is only 8 bits but here I am told that it actua...


java - How to improve Netbeans performance?

Is there a real way to get Netbeans to load and work faster? It is too slow and gets worse when you have been coding for some time. It eats all my RAM. I am on a Windows machine, specifically Windows Server 2008 Datacenter Edition x64, 4Gb of RAM, 3Ghz Core 2 Duo processor, etc. I am using the x64 JDK. I use the NOD32 Antivirus since for me it is the best in machine performance. In Task Manage...


performance - Java File Cursor

Is there some library for using some sort of cursor over a file? I have to read big files, but can't afford to read them all at once into memory. I'm aware of java.nio, but I want to use a higher level API. A little backgrond: I have a tool written in GWT that analyzes submitted xml documents and then pretty prints the xml, among other things. Currently I'm writing the pretty printed xml to a temp file (my lib woul...


performance - Accelerate 2D images in Java *without* disturbing JMenus

Already implemented performance boosters : - Get compatible image of GraphicsConfiguration to draw on - Enable OpenGL pipeline in 1.5: Not possible due to severe artifacts So far I am fine, the main profiled bottleneck of the program is drawing an image with several thousand tiles. Unfortunately it is not regular, else I simply could set pixels and scale them. I accerelated the image with VolatileImages and own ren...


performance - Measuring Java execution time, memory usage and CPU load for a code segment

For a particular segment of Java code, I'd like to measure: Execution time (most likely thread execution time) Memory usage CPU load (specifically attributable to the code segment) I'm a relative Java novice and am not familiar with how this might be achieved. I've been referred to


Can anyone quantify performance differences between C++ and Java?

Java was initially slow before the JIT but today performance is pretty close to C++. I want to know if someone has done measurable performance comparisons between the two languages? Where does Java fall short when compared to C++? Java provides many productivity gains to developers so they can write applications much quicker because of garbage college, lack of pointers, etc. Applications such as Firefox, Webkit ...


performance - ArrayList vs. Vectors in Java if thread safety isn't a concern

Is there really that much of a difference between the performance of Vector and ArrayList? Is it good practice to use ArrayLists at all times when thread safety isn't an issue?






Still can't find your answer? Check out these amazing Java communities for help...



Java Reddit Community | Java Help Reddit Community | Dev.to Java Community | Java Discord | Java Programmers (Facebook) | Java developers (Facebook)



top