Which is more efficient, a for-each loop, or an iterator?

后端 未结 7 1452
别那么骄傲
别那么骄傲 2020-11-22 16:00

Which is the most efficient way to traverse a collection?

List  a = new ArrayList();
for (Integer integer : a) {
  integer.toSt         


        
相关标签:
7条回答
  • 2020-11-22 16:40

    The foreach underhood is creating the iterator, calling hasNext() and calling next() to get the value; The issue with the performance comes only if you are using something that implements the RandomomAccess.

    for (Iterator<CustomObj> iter = customList.iterator(); iter.hasNext()){
       CustomObj custObj = iter.next();
       ....
    }
    

    Performance issues with the iterator-based loop is because it is:

    1. allocating an object even if the list is empty (Iterator<CustomObj> iter = customList.iterator(););
    2. iter.hasNext() during every iteration of the loop there is an invokeInterface virtual call (go through all the classes, then do method table lookup before the jump).
    3. the implementation of the iterator has to do at least 2 fields lookup in order to make hasNext() call figure the value: #1 get current count and #2 get total count
    4. inside the body loop, there is another invokeInterface virtual call iter.next(so: go through all the classes and do method table lookup before the jump) and as well has to do fields lookup: #1 get the index and #2 get the reference to the array to do the offset into it (in every iteration).

    A potential optimiziation is to switch to an index iteration with the cached size lookup:

    for(int x = 0, size = customList.size(); x < size; x++){
      CustomObj custObj = customList.get(x);
      ...
    }
    

    Here we have:

    1. one invokeInterface virtual method call customList.size() on the initial creation of the for loop to get the size
    2. the get method call customList.get(x) during the body for loop, which is a field lookup to the array and then can do the offset into the array

    We reduced a ton of method calls, field lookups. This you don't want to do with LinkedList or with something that is not a RandomAccess collection obj, otherwise the customList.get(x) is gonna turn into something that has to traverse the LinkedList on every iteration.

    This is perfect when you know that is any RandomAccess based list collection.

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