Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Agile forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Using Enumeration/Iterator over looping around,

 
Bimal Patel
Ranch Hand
Posts: 130
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Ranchers,

I have one confusion. What is a better method to iterate a collection(list/vector etc)? Either iterate it by a simple "for" loop or to use an iterator or enumeration! Which one is more optimized? I think iterating over a loop. Or it depends from case to case? If yes how? Is there any thread posted on this topic before? If anyone knows, let me have the link to that thread.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24208
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For ArrayList or Vector, the simple for loop with "get()" will be a little faster. For other Collections, most notably LinkedList, the "get()" loop will be vastly slower. And for other Collections, of course, you don't have a choice -- the Iterator (or Enumeration) is all you get.

Most of the time, worry about the clarity of the code, not little micro-performance issues like this.
 
Ken Blair
Ranch Hand
Posts: 1078
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I code using the interface rather than the implementation and as such I prefer using an Iterator. A for loop can be very fast or very slow depending on the specific implementation. By using the Iterator I can rest assured that regardless of the implementation it's going to be reasonably efficient. The common idiom I see is:



In 1.5 you can use the new foreach loop with any Iterable too, which is convenient.
 
Tony Morris
Ranch Hand
Posts: 1608
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
For ArrayList or Vector, the simple for loop with "get()" will be a little faster.


Can you please explain this?
If "what I am thinking" is right, this statement is a generalisation that can be invalidated by introducing a sub-context that has probably been overlooked.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24208
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Tony Morris:


Can you please explain this?


If nothing else, both your hand-coded loop and the Iterator would do the same exact thing under the covers; the "little bit faster" is then due to your needing to construct the iterator. Also with the Iterator, the loop index is out on the heap; with the hand-coded loop, it's in a register. Faster access, shorter instructions. But this is all just rationalization -- I've seen people make the measurement, and the hand-coded for-loop does come out faster.
 
Bimal Patel
Ranch Hand
Posts: 130
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Thanks for your views. What I think, if the chosen one is Iterator, a new object would be created and in terms of volume, it takes some of the memory. Am I correct? If yes, then, by looping around, the purpose is solved to iterate, why to use Iterator or Enumeration?

I agree that for commonly used Collections, looping is possible by get(cnt) methods. Does that mean, iterator or enumeration should be avoided if one is dealing with such collections(ArrayList, Vector etc)?
 
Jim Yingst
Wanderer
Sheriff
Posts: 18671
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
[Bimal]: What I think, if the chosen one is Iterator, a new object would be created and in terms of volume, it takes some of the memory. Am I correct?

The creation of an Iterator does take some memory, true. But you only need to do it once for the entire loop. And most Iterators have a very small memory footprint anyway - they're typically just lightweight views into some already-existing structure. It's possible there are some exceptions out there, but they should be very rare, and fixable by good design.

If yes, then, by looping around, the purpose is solved to iterate, why to use Iterator or Enumeration?

EFH already addressed this, didn't he? If there's any chance your List might be a LinkedList or other implementation which has an extremely inefficient get() method, the Iterator can be much faster.

Also, if you don't have a List at all, but instead have a Set or other Collection, then you don't have a get() method, and if you want to be able to loop through the entire Collection, Iterator is your only choice. Well, that or use toArray[], but that seems a waste of memory, and unlikely to be any faster. (Not when you include the time to create and populate the array, as well as loop through it.)

I agree that for commonly used Collections, looping is possible by get(cnt) methods. Does that mean, iterator or enumeration should be avoided if one is dealing with such collections(ArrayList, Vector etc)?

I would say no, in general. Unless you are sure that the ArrayList or Vector will not be changed to something else some day. If you really want to optimize performance, and don't mind writing extra code to do so (note this is probably a bad idea already, in most cases) then you can do something like this:

You can find similar code in the source code for several methods in the Collections class. Might be worth a look. Most of the time though, it's not worth the time & trouble to optimize this sort of thing, and using Iterator is a pretty safe choice. Exceptions to this are pretty rare, I think. However it's most always a good idea to just test and see, if you have doubts.

----

[Tony]: If "what I am thinking" is right, this statement is a generalisation that can be invalidated by introducing a sub-context that has probably been overlooked.

Hmmm. Are you thinking of the possibility that the ArrayList or Vector is actually a subclass of ArrayList or Vector, with different performance characteristics? Or something else?
[ March 28, 2006: Message edited by: Jim Yingst ]
 
Mahadevan Gorti SS
Greenhorn
Posts: 18
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
As we have already covered all cases about Iterator/Enum/get cases, here are some additional points.

Here is a practical case where you would prefer a get from a Vector/AttayList over Iterator/Enumeration:
* Handling some tight loop of code where one has to process events more than 100/sec(for example). In each event loop, if one has to go thru the for-loop/Iterator(and the underlying data-structure is Vector/ArrayList/etc), for-loop is preferable for reason
-- It is faster than Iterator
-- It creates less garbage(so is the GC CPU utilization)
 
ak pillai
author
Ranch Hand
Posts: 288
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Most of the time, worry about the clarity of the code, not little micro-performance issues like this.


Could not agree more. maintainability and readability are more important than gaining some few micro-seconds.
 
Bimal Patel
Ranch Hand
Posts: 130
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,
Originally posted by Jim Yingst:

The creation of an Iterator does take some memory, true. But you only need to do it once for the entire loop. And most Iterators have a very small memory footprint anyway - they're typically just lightweight views into some already-existing structure.

Originally posted by ak pillai:

Could not agree more. maintainability and readability are more important than gaining some few micro-seconds.


Think of a scenario that you've used Iterator/Enumeration everywhere, eventhough for some collections it could be avoided like ArrayList and Vector in an enterprise system filled with lots of classes like around 400 to 500. Out of that, even if in around 100 classes, Iterator/Enumeration is used, think about the objects which need to be GCed. What do you think?

Originally posted by Jim Yingst:

EFH already addressed this, didn't he? If there's any chance your List might be a LinkedList or other implementation which has an extremely inefficient get() method, the Iterator can be much faster.

I was addressing this in case of using ArrayList/Vector kind of enumeration where get() method is available and which is efficient.

Originally posted by Jim Yingst:

Also, if you don't have a List at all, but instead have a Set or other Collection, then you don't have a get() method, and if you want to be able to loop through the entire Collection, Iterator is your only choice. Well, that or use toArray[], but that seems a waste of memory, and unlikely to be any faster. (Not when you include the time to create and populate the array, as well as loop through it.)

I would totally agree. I even don't think of using toArray[] ever! Its really not a good idea. But again, I am only concerned about the collections which has efficient get() method.

Originally posted by Jim Yingst:

I would say no, in general. Unless you are sure that the ArrayList or Vector will not be changed to something else some day. If you really want to optimize performance, and don't mind writing extra code to do so (note this is probably a bad idea already, in most cases) then you can do something like this:
.
.
.

In the example you've given, I would say that there is no need of checking the instanceof rather straight away use the iterator! And you're right that one should only use get() if it is sure to expect only such kind of collection and not anything else.
[ March 29, 2006: Message edited by: Bimal Patel ]
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic