Srujan Kumar Gulla
Srujan Kumar Gulla

Reputation: 5841

Is Java foreach loop an overkill for repeated execution

I agree foreach loop reduces typing and good for readability.

A little backup, I work on low latency application development and receive 1Million packets to process per second. Iterating through a million packets and sending this information across to its listeners. I was using foreach loop to iterate through the set of listeners.

Doing profiling i figured there are a lot of Iterator objects created to execute foreach loop. Converting foreach loop to index based foreach I observed a huge drop in the number of objects created there by reducing no. of GC's and increasing application throughput.

Edit: (Sorry for confusion, making this Q more clearer) For example i have list of listeners(fixed size) and i loop through this forloop a million times a second. Is foreach an overkill in java?

Example:

for(String s:listOfListeners)
{
   // logic
}

compared to

for (int i=0;i<listOfListeners.size();i++)
{
   // logic
}

Profiled screenshot for the code

for (int cnt = 0; cnt < 1_000_000; cnt++)
{
    for (String string : list_of_listeners)
    {
         //No Code here 
    }
}

enter image description here

Upvotes: 7

Views: 1903

Answers (5)

Matsemann
Matsemann

Reputation: 21784

EDIT: The question has changed so much since I wrote my answer that I'm not sure what I'm answering at the moment.

Looking up stuff with list.get(i) can actually be a lot slower if it's a linked list, since for each lookup, it has to traverse the list, while the iterator remembers the position.

Example:

list.get(0) will get the first element
list.get(1) will first get the first element to find pointer to the next
list.get(2) will first get the first element, then go to the second and then to the third
etc.

So to do a full loop, you're actually looping over elements in this manner:

0
0->1
0->1->2
0->1->2->3
etc.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500515

EDIT: Answering the vastly different question of:

For example i have list of listeners(fixed size) and i loop through this forloop a million times a second. Is foreach an overkill in java?

That depends - does your profiling actually show that the extra allocations are significant? The Java allocator and garbage collector can do a lot of work per second.

To put it another way, your steps should be:

  1. Set performance goals alongside your functional requirements
  2. Write the simplest code you can to achieve your functional requirements
  3. Measure whether that code meets the functional requirements
  4. If it doesn't:
    • Profile to work out where to optimize
    • Make a change
    • Run the tests again to see whether they make a significant difference in your meaningful metrics (number of objects allocated probably isn't a meaningful metric; number of listeners you can handle probably is)
    • Go back to step 3.

Maybe in your case, the enhanced for loop is significant. I wouldn't assume that it is though - nor would I assume that the creation of a million objects per second is significant. I would measure the meaningful metrics before and after... and make sure you have concrete performance goals before you do anything else, as otherwise you won't know when to stop micro-optimizing.


Size of list is around a million objects streaming in.

So you're creating one iterator object, but you're executing your loop body a million times.

Doing profiling i figured there are a lot of Iterator objects created to execute foreach loop.

Nope? Only a single iterator object should be created. As per the JLS:

The enhanced for statement is equivalent to a basic for statement of the form:

    for (I #i = Expression.iterator(); #i.hasNext(); ) {
        VariableModifiersopt TargetType Identifier =
            (TargetType) #i.next();
        Statement
    }

As you can see, that calls the iterator() method once, and then calls hasNext() and next() on it on each iteration.

Do you think that extra object allocation will actually hurt your performance significantly?

How much do you value readability over performance? I take the approach of using the enhanced for loop wherever it helps readability, until it proves to be a performance problem - and my personal experience is that it's never hurt performance significantly in anything I've written. That's not to say that would be true for all applications, but the default position should be to only use the less readable code after proving it will improve things significantly.

Upvotes: 10

Deepak Bala
Deepak Bala

Reputation: 11185

Is this comparison even fair ? You are comparing using an Iterator Vs using get(index)

Furthermore, each loop would only create one additional Iterator. Unless the Iterator is itself inefficient for some reason, you should see comparable performance.

Upvotes: 0

Alex Kreutznaer
Alex Kreutznaer

Reputation: 1170

I do not think you should worry about the effectiveness here.

Most of time is consumed by your actual application logic (in this case - by what you do inside the loop).

So, I would not worry about the price you pay for convenience here.

Upvotes: 0

Ernest Friedman-Hill
Ernest Friedman-Hill

Reputation: 81684

The "foreach" loop creates just one Iterator object, while the second loop creates none. If you are executing many, many separate loops that execute just a few times each, then yes, "foreach" may be unnecessarily expensive. Otherwise, this is micro-optimizing.

Upvotes: 6

Related Questions