why is the enhanced for loop more efficient than the normal for loop

后端 未结 7 1734
一整个雨季
一整个雨季 2020-12-01 00:35

I read that the enhanced for loop is more efficient than the normal for loop here:

http://developer.android.com/guide/practices/performance.html#fo

相关标签:
7条回答
  • 2020-12-01 00:43

    The foreach loop is as efficient as this kind of loop:

    for (Iterator<Foo> it = list.iterator(); it.hasNext(); ) {
         Foo foo = it.next();
         ...
    }
    

    because it's strictly equivalent.

    If you iterate through a list using

    int size = list.size();
    for (int i = 0; i < size; i++) {
        Foo foo = list.get(i);
        ...
    }
    

    Then the foreach loop will have an equivalent performance as your loop, but only for ArrayList. In case of a LinkedList, your loop will have abysmal performance, because at each iteratioon, it will have to traverse all the nodes of the list until it gets to the ith element.

    The foreach loop (or the loop based on an iterator, which is the same), doesn't have this problem, since the iterator keeps a reference to the current node and simply goes to the next at each iteration. It's the bast choice, because it works fine with all types of lists. It also expresses the intent more clearly, and is safer because you don't risk to increment the index inside the loop, or use the wrong index in case of nested loops.

    0 讨论(0)
  • 2020-12-01 00:45

    From Effective Java :

    The standard idiom for looping through an array doesn’t necessarily result in redundant checks. Modern JVM implementations optimize them away.

    But Josh Bloch doesn't describe how JVM optimizes them.

    0 讨论(0)
  • 2020-12-01 00:54

    all answers are good,and I think no more answers are needed, but I just want to point out that:

    The enhanced for statement can be used only to obtain array elements

    it cannot be used to modify elements.

    If your program needs to modify elements, use the traditional counter-controlled for statement.

    take a look

    int[] array = { 1, 2, 3, 4, 5 };
    for (int counter = 0; counter < array.length; counter++)
        array[counter] *= 2;
    

    We could not use the enhanced for statement because we’re modifying the array’s elements.

    0 讨论(0)
  • 2020-12-01 01:02

    I am myself surprised in a little experiment i did today with above mentioned points. So what i did was that i inserted a certain number of elements to a linked list and iterated through it using the above mentioned three methods 1)using advanced for loop 2) using Iterator 3) using simple loop and get()
    I guess programmers such as you guys can better understand what i did by seeing the code.

    long advanced_timeElapsed,iterating_timeElapsed,simple_timeElapsed;
        long first=System.nanoTime();
        for(Integer i: myList){
            Integer b=i;
        }
        long end= System.nanoTime();
        advanced_timeElapsed=end-first;
        System.out.println("Time for Advanced for loop:"+advanced_timeElapsed);
        first=System.nanoTime();
        Iterator<Integer> it = myList.iterator();
        while(it.hasNext())
        {
            Integer b=it.next();
        }
        end= System.nanoTime();
        iterating_timeElapsed=end-first;
        System.out.println("Time for Iterating Loop:"+iterating_timeElapsed);
        first=System.nanoTime();
        int counter=0;
        int size= myList.size();
        while(counter<size)
        {
            Integer b=myList.get(counter);
            counter++;  
        }
        end= System.nanoTime();
        simple_timeElapsed=end-first;
        System.out.println("Time for Simple Loop:"+simple_timeElapsed);
    

    The results where not what i expected . Following is the graph of time elapsed in 3 cases. Time Elapsed Graph

    Y axis-time elapsed X axis-test case
    test case1:10 inputs
    test case2:30 inputs
    test case3:50 inputs
    test case4:100 inputs
    test case5:150 inputs
    test case6:300 inputs
    test case7:500 inputs
    test case8:1000 inputs
    test case9:2000 inputs
    test case10:5000 inputs
    test case11:10000 inputs
    test case12:100000 inputs

    Here you can see that simple loop performs way better than others.if you find any errors in the code above , do reply and i will check again. will update on this further after i dig through bytecode and see what is happening under the hood. My apologies for such a long response but i like to be descriptive. Philip

    0 讨论(0)
  • 2020-12-01 01:02

    I read that enhanced for loop is efficient than normal for loop.

    Actually sometimes its less efficient for the program, but most of the time its exactly the same.

    Its more efficient for the developer, which is often far more important

    A for-each loop is particularly useful when iterating over a collection.

    List<String> list = 
    for(Iterator<String> iter = list.iterator(); list.hasNext(); ) {
        String s = list.next();
    

    is more easily written as (but does the same thing as, so its no more efficient for the program)

    List<String> list = 
    for(String s: list) {
    

    Using the "old" loop is slightly more efficient when access a randomly accessible collection by index.

    List<String> list = new ArrayList<String>(); // implements RandomAccess
    for(int i=0, len = list.size(); i < len; i++) // doesn't use an Iterator!
    

    Using a for-each loop on a collection always uses an Iterator which is slightly less efficient for random access lists.

    AFAIK, use a for-each loop is never more efficient for the program, but like I said the efficiency of the developer is often far more important.

    0 讨论(0)
  • 2020-12-01 01:04

    The for-each uses the Iterator interface. I doubt that it is more efficient than the "old" style. The Iterator also needs to check the size of the list.

    It's mostly for readability.

    It should be faster for non-random-access collections like LinkedList, but then the comparison is unfair. You would not have used to second implementation (with slow indexed access) anyway.

    0 讨论(0)
提交回复
热议问题