2

What is the gain, if there is any, from doing this:

for (int i = 0, size = foo.size(); i < size; i++) {}

instead of this:

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

(foo is a List object)

Adri Van Houdt
  • 435
  • 4
  • 13
  • Depends on what you are doing inside the for loop. Let's say you want to add size elements in your Foo list which contains already one or more elements (okay that seems stupid), the second one will result in an infinite loop until you have no more memory availabe while the first one will correctly add size elements. – Alexis C. May 13 '14 at 09:30
  • 5
    Maybe there is for the first few times the loop is run but then the JIT will make these two equivalent; so, the answer: no gain – fge May 13 '14 at 09:30
  • 1
    @fge: Well, you're assuming that `size()` is a cheap method. It *might* not be. In reality, it usually will be though. – Jon Skeet May 13 '14 at 09:32
  • @MatthewWatson: It's your imagination, as far as I'm aware. It's been a Java question as long as I've been looking at it. – Jon Skeet May 13 '14 at 09:37
  • @JonSkeet the op states that `foo` is a `List`. – assylias May 13 '14 at 09:37
  • 1
    @assylias Doesn't mean you can't have a `List` with an expensive `size()` function. – awksp May 13 '14 at 09:38
  • @assylias: Yes, and? The documentation for `List.size()` doesn't say it'll be fast. – Jon Skeet May 13 '14 at 09:38

2 Answers2

5

Well, it means you only evaluate size() once instead of once per iteration. Theoretically, that could be a performance win - it's just possible that computing the size is actually expensive. (For example, you could have a linked list implementation which doesn't remember its size, but actually has to traverse the whole list. Arguably if you find yourself in that situation, the better solution is simply to use a better data structure... if size() is expensive, then access by index is likely to be expensive too.)

In reality, the standard collections have very fast size() methods, so it's usually irrelevant, and harms readability (IMO). Of course, if you don't need the index, it's more readable to use an enhanced for loop anyway...

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • To be complete, one could also mention that any object implementing the (marker) `RandomAccess` interface will be actually faster to access by index than in a foreach loop! `ArrayList` is such a class – fge May 13 '14 at 09:35
  • @fge: I think "will" is a strong statement here. `RandomAccess` suggests it will be fast - not necessarily *faster* than a foreach loop. And the benefit of the foreach loop is primarily in terms of readability. – Jon Skeet May 13 '14 at 09:36
  • Thanks for the quick answer. I was thinking the same but I wanted confirmation. – Adri Van Houdt May 13 '14 at 09:57
1

For the first case size of the List is calculated only once.

For the second case every time the size of List foo is calculated during the itrations.

For me if foo List is of type String i For Each loop

for(String str: foo){

}
Rakesh KR
  • 6,357
  • 5
  • 40
  • 55
  • I need the index in the program I'm writing atm but this is indeed the best option if you don't need the index – Adri Van Houdt May 13 '14 at 09:57
  • @AdriVanHoudt foreach was meant to hide the iterator. You must do the normal For loop in order to get the current iteration. For More Look on http://stackoverflow.com/questions/477550/is-there-a-way-to-access-an-iteration-counter-in-javas-for-each-loop – Rakesh KR May 14 '14 at 02:28
  • I know this, I was just wondering about the special variant of the for loop with iterator. But thanks for the response! – Adri Van Houdt May 14 '14 at 12:55