Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 242
Srujan Kumar Gulla Avatar asked Apr 10 '13 18:04

Srujan Kumar Gulla


1 Answers

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.

like image 200
Jon Skeet Avatar answered Nov 16 '22 00:11

Jon Skeet