Welcome to MSDN Blogs Sign in | Join | Help

Efficiency of iteration over arrays?

I got the following question on email:

Question:

Which one of these three loops is the most efficient? How can I prove the answer?

I've listed the source code below. The three loops are:

  1. Foreach over an int array
  2. Simple for over an int array
  3. For over an int array, hoisting out the length value

On questions such as these, there are two ways to find the answer. The first is to build the code and look at the generated IL (or the resulting assembly, remembering that you get debug code if you run in the debugger. Attach to a running process, and then you get the optimized native code), or to time the code with a stopwatch.

In this case, I chose the IL approach, because it was quicker.  For arrays, versions #1 and #2 produce similar IL, and should produce very similar execution speed (I'm too lazy to actually time them today). So, I would choose the foreach version unless I needed the index.

In fact, I would advocate this position even if for loops are faster, to avoid the sin of premature optimization. It remains true that only 10% of the code needs optimization, and that algorithmic efficiency is often the driving factor.

The third option is to be avoided. The JIT looks for the pattern in version #2, and knows how to optimize it. If you pull the value out into a temporary, it may not optimize it. Of course, you know that because you've been measuring your important scenarios...

Code 

int [] foo = new int[100];
// version 1:
foreach ( int i in foo)
  Console.WriteLine( i.ToString( ));
 
// Version 2:
for ( int index = 0;
  index < foo.Length;
  index++ )
  Console.WriteLine( foo[index].ToString( ));
 
// Version 3:
int len = foo.Length;
for ( int index = 0;
  index < len; 
  index++ )
  Console.WriteLine( foo[index].ToString( ));
Published Sunday, April 18, 2004 12:36 PM by ericgu
Filed under: ,

Comments

Sunday, April 18, 2004 1:14 PM by Scott Galloway

# re: Efficiency of iteration over arrays?

Would I be right in thinking that this only applies to arrays? I tried this on an ArrayList and got this from Reflector's IL decompilation:
ArrayList list1;

string text1;

IEnumerator enumerator1;

IDisposable disposable1;

list1 = new ArrayList();

enumerator1 = list1.GetEnumerator();

try

{

while (enumerator1.MoveNext())

{

text1 = ((string) enumerator1.Current);

Console.WriteLine(text1);



}



}

finally

{

disposable1 = (enumerator1 as IDisposable);

if (disposable1 != null)

{

disposable1.Dispose();



}


Trying timing tests on this comapared to the simple for it does seem to be significantly slower looping over large arraylists.
Sunday, April 18, 2004 2:13 PM by Justin Rogers

# re: Efficiency of iteration over arrays?

There is a somewhat detailed analysis of this on my blog. Eric, if you could be so kind as to point out any inaccuracies it would be very nice.

http://weblogs.asp.net/justin_rogers/archive/2004/03/26/97230.aspx

I realized just now I never posted any actual numbers and instead left the test code at the end for people to test if they wanted to, but that should be okay.
Sunday, April 18, 2004 6:56 PM by Ramblings of a Code Monkey

# Efficiency of Array Iteration

Eric Gunnerson has an interesting post about the efficiency of iterating over an array using different methods. The three methods listed are: foreach over an int array Simple fore over an int array forover an int array, hoisting out the...
Sunday, April 18, 2004 9:03 PM by Anatoly Lubarsky Blog

# EricGu says

Sunday, April 18, 2004 9:04 PM by Anatoly Lubarsky Blog

# EricGu says

Sunday, April 18, 2004 6:44 PM by Lavos

# re: Efficiency of iteration over arrays?

In the last 4 weeks, in nearly every instance where I started with a foreach, I ended up switching to a for loop because I needed the index for one reason or another.

Of course, I was mainly doing code-gen stuff and was trying to get my commas right, but I see that trend holding true at least part of the time.

I'm beginning to just default to for's for at least codegen to avoid constantly refactoring the loop. :(

If IEnumerator/IEnumerable supported something like STL's compare to the end/start properties so I can check if the enumeratorion was done, I'd be a happy camper.
Monday, April 19, 2004 8:30 AM by Joe Duffy

# re: Efficiency of iteration over arrays?

Interesting. I suppose this is a holdover from C/C++, but I always choose a variation of #3 for loop iteration (should I need the current index during the loop, that is)...

for (int i = 0, c = foo.Length; i < c; i++)
Console.WriteLine(foo[i].ToString());

Why would this impact post-JIT performance, though -- how much more optimization can take place? c is already a stack-based variable and should probably end up as a register due to the frequent jump test (i < c), etc.
Monday, April 19, 2004 12:21 PM by Bryant Likes's Blog

# Eric Gunnerson on Loops

Monday, April 19, 2004 12:29 PM by Bryant Likes's Blog

# Eric Gunnerson on Loops

Monday, April 19, 2004 9:55 AM by B.Y.

# re: Efficiency of iteration over arrays?

I think it's going too far if "Simple for over an int array" is considered an optimization.

Monday, April 19, 2004 11:10 AM by Joe Duffy

# re: Efficiency of iteration over arrays?

FYI, I did some timing tests myself, and was surprised at how large of a difference the "hand optimization" makes... And, not a good difference, either! ;)

The wonders of modern-day JIT optimization.

http://www.bluebytesoftware.com/blog/PermaLink.aspx?guid=16a1cf7f-73f6-45a9-9aff-e88264b13b0e
Monday, April 19, 2004 6:10 PM by public MattBerther : ISerializable

# foreach and performance

One statement that I have heard incessantly is that foreach over an array is slower than for (int i = 0; i &lt; array.Length; i++). Finally, some good people have debunked this myth: Kevin Ransom -- To foreach or not...
Tuesday, April 20, 2004 11:19 PM by Joshua Allen

# re: Efficiency of iteration over arrays?

Eric, I did all three of these in ildasm, and the third option was two instructions shorter (in the loop) than the second, which in turn was two instructions shorter than the first. People love to memorize "rules of thumb" and apply them, but I really think this whole swarm of threads is doing the blogsphere a disservice. Not only are your numbers bad; so are Joe Duffy's and Kevin Ransom's. And people are now running around telling each other "best practices" based off of numbers that are flawed. Besides, there are differences in semantics of all three techniques, and these differences could very well be important. Hoisting the length is not just an attempt at optimization, for example. Finally, telling someone "don't do loop 'x' because the JIT will not understand it" is just as bad as telling them to "hand optimize 'foo'" -- both are bad, bad, bad
Thursday, April 22, 2004 2:11 PM by The Farm: The Tucows Developers' Hangout

# Loopy Decisions

<p>In his blog, <span style="font-style: italic;">Better Living Through Software</span>, Joshua Allen looks at three different ways to loop in C# from an optimizing-for-performance point of view:</p><p><code>foreach (int i in foo) {}<br>
<br>
for (int i = 0; i &lt; foo.Length; i++) {}<br>
<br>
int len = foo.Length; for (int i = 0; ...
Tuesday, April 27, 2004 3:03 PM by chrisbro

# re: Efficiency of iteration over arrays?

#3 can be a huge massive performance gain, depending on the complexity of the .Length operator. For instance, in some collections (Hello, XmlNodeList) calling .Length actually recomputers the length of the array with every pass. If I'm doing work that I explicitly know will not alter it, then I should move .Length into a temporary variable and get a performance gain.

For instance, I had an XML document with 2800 items. for(x=0; x<xmlnl.Length;x++){} took something like 900 million function calls to evaluate, because of the .Length.
Saturday, May 01, 2004 11:52 PM by Geek Noise

# Geek Notes 2004-05-01

Saturday, May 01, 2004 11:52 PM by Geek Noise

# Geek Notes 2004-05-01

Monday, May 03, 2004 4:24 AM by Moi

# re: Efficiency of iteration over arrays?

So we are supposed to avoid certain códe constructs (in this case we are supposed to write 2 instead of 3) because the compiler sucks? Gimme a break.
Saturday, July 03, 2004 3:08 AM by Dan

# re: Efficiency of iteration over arrays?

so true Moi. Hopefully we will see some maturity with MS's compiler... but I doubt that happens for a while. Hats off to them for the .NET framework though.
Saturday, December 18, 2004 10:50 AM by MBA

# MBA

Helpful For MBA Fans.

# Better Living through Software &raquo; Blog Archive &raquo; Loopy Decisions

# Better Living through Software &raquo; Blog Archive &raquo; Loopy Decisions

# public MattBerther : ISerializable &raquo; Blog Archive &raquo; foreach and performance

New Comments to this post are disabled
 
Page view tracker