none
foreach or for loop? to Improve Performance - C# Code RRS feed

  • Question

  • To iterate collection/list or array or ...... which one the best foreach or for loop?

    or

    Can you please give me some sample (best) scenario to use/choose foreach and for loop to improve performance?


    Work Smart, Not Hard Be Confident. Go Next.
    Wednesday, May 12, 2010 2:09 PM

Answers

  • In summary:

    * For loops and foreach loops with arrays are quite similar in speed but "for" is usually faster.
    * Arrays are much faster than lists.
    * The fastest approach in general is to use "for" with an array, if possible.

    We've done a lot of research and timing of real code in this area, since we are writing ECG analysis code in C#, which has to perform many calculations on large arrays. In almost all cases, 'for' has been a little faster than 'foreach'.

    Thursday, May 13, 2010 9:43 AM
  • Hi Yasser Zamani,

     

    Sorry but i would like to correct you here. i find there is correction in your code and due to that it seems that foreach loop is much faster than for loop:

     

    in your code, if i know that i am going to use the object from an index multiple times within loop then why i will always use the index key, i should directly retrieve the object first and then use that object furture - like see corrected code below:

     

     

    for(int i=0;i<x.Length;i++)
    {
     object o = x[i];
     if(o.a==o.b && o.c==o.d && o.e==o.f);
    }

     

     

    I still think that for loop is always faster than foreach in any case - only if we have used the right logic.


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    Wednesday, May 12, 2010 5:55 PM

All replies

  • The array because:

    1. No need to cast when add/remove/retrieve the object.

    2. Light weight.


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    Wednesday, May 12, 2010 2:18 PM
  • Sorry i made some mistake in my question. please read the question now.
    Work Smart, Not Hard
    Wednesday, May 12, 2010 2:30 PM
  • I still have same answer.
    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    Wednesday, May 12, 2010 2:36 PM
  • Arrays are much faster than List, if you can use them.

    foreach versus for doesn't make much difference for Arrays or Lists - but use a Stopwatch to time things to be sure.

    Wednesday, May 12, 2010 3:40 PM
  • Matt, i tested. it gave me same time till loop count 200000.

    But when i tried 2000000 and 20000000 'FOR' loop was faster. This could be becasue of  additional register shifting need when using 'FOREACH' loop. But diffrence is very narrow.


    Thanks Mike -------- Mark best answers as Answer ----------
    Wednesday, May 12, 2010 4:11 PM
  • Can you use the new .NET 4 features like Parellel.For statements? I would like to see the results. But to answer the question arrays are much faster than a list
    Wednesday, May 12, 2010 5:17 PM
  • A for loop is always faster then a foreach.

    I recall years ago a article in CodeProject about this that stirred much controversy


    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Wednesday, May 12, 2010 5:22 PM
  • For loop is faster because while looping it is not required to perform casting and type validation compare to foreach loop.

    but on other side, when you try to get the object using its index, the casting and validation occur - but still not expansive than foreach loop.

     


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    Wednesday, May 12, 2010 5:31 PM
  • Why are you "marking" every one of your posts as the answer? (I know what you say is correct, but calm down brother on the proposing)

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Wednesday, May 12, 2010 5:33 PM
  • Hi Prabhu.

    Thank you for this post.

    I guess that it's dependent to index accesses in loop's body. e.g. I think that

    foreach(x in y)
    {
     if(x.a==x.b && x.c==x.d && x.e==x.f);
    }
    Should be quicker than
    for(int i=0;i<x.Length;i++)
    {
     if(x[i].a==x[i].b && x[i].c==x[i].d && x[i].e==x[i].f);
    }

    Please verify this by your code, I'm interested in results.

    Thank you.


    WHAT'S NEW IN THE .NET FRAMEWORK 4:
    Article: Comparison of parallel and sequential computing in .NET Framework
    Wednesday, May 12, 2010 5:42 PM
  • If speed is a concern, always use a for loop.

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Wednesday, May 12, 2010 5:48 PM
  • Hi Yasser Zamani,

     

    Sorry but i would like to correct you here. i find there is correction in your code and due to that it seems that foreach loop is much faster than for loop:

     

    in your code, if i know that i am going to use the object from an index multiple times within loop then why i will always use the index key, i should directly retrieve the object first and then use that object furture - like see corrected code below:

     

     

    for(int i=0;i<x.Length;i++)
    {
     object o = x[i];
     if(o.a==o.b && o.c==o.d && o.e==o.f);
    }

     

     

    I still think that for loop is always faster than foreach in any case - only if we have used the right logic.


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    Wednesday, May 12, 2010 5:55 PM
  • Arrays are much faster than List, if you can use them.

    foreach versus for doesn't make much difference for Arrays or Lists - but use a Stopwatch to time things to be sure.

     

    Ashish Khandelwal

     

    Run some speed tests to be sure.  Prove it, that a for loop is faster.

    There is not much difference between the two loop types.  What is done inside of the loop makes a bigger difference, which includes what type of collection you are referencing and accessing.


    Mark the best replies as answers. "Fooling computers since 1971."
    Wednesday, May 12, 2010 6:24 PM
    Moderator
  • I agree with Rudy to perform some tests.

    However, this has been done thousands of times. Using a for over a foreach is readily known to be faster.

    http://stackoverflow.com/questions/365615/in-net-which-loop-runs-faster-for-or-foreach

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Wednesday, May 12, 2010 6:28 PM
  • Mr. Rudegod2,

     

    That's what i was trying to say in my latest post. However, I just need your comment that if we have same peace of code one is written using foreach loop and another is using for loop, then which one will be fast (even if it is little) - about why i am saying for loop is fast, just scroll up to see the reason.

     

    Thanks...


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com
    Wednesday, May 12, 2010 6:34 PM
  • See

    http://msdn.microsoft.com/en-us/library/ms973839.aspx

    "a For loop on strings is up to five times faster than using foreach"

    (In the example they showed)


    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Wednesday, May 12, 2010 6:36 PM
  • The difference is not as high as that in any of the programs I've tested. Normally foreach (on an int array in a RELEASE rather than a DEBUG build) is only about 50% faster.

    The following program gives the following results on my system (Windows 7, x64)

    x86 RELEASE version:

    Foreach loop took: 00:00:00.7145486
    For loop took:       00:00:00.5330092

    AnyCPU RELEASE version:

    Foreach loop took: 00:00:00.7182685
    For loop took: 00:00:00.7195114

    So the for loop is not any faster at all for the 64 bit version, but is a bit faster for the x86 build. What's interesting here is the difference between 32 and 64 bit versions!

    Here's the code:

    using System;
    using System.Diagnostics;
    
    namespace ConsoleApplication2
    {
      class Program
      {
        static void Main(string[] args)
        {
          int[] array = new int[1000000];
    
          Stopwatch sw = new Stopwatch();
          sw.Start();
    
          for (int i = 0; i < 1000; ++i)
          {
            Test1(array);
          }
    
          sw.Stop();
          Console.WriteLine("Foreach loop took: " + sw.Elapsed);
          sw.Restart();
    
          for (int i = 0; i < 1000; ++i)
          {
            Test2(array);
          }
    
          sw.Stop();
          Console.WriteLine("For loop took: " + sw.Elapsed);
        }
    
        static int Test1(int[] array)
        {
          int total = 0;
    
          foreach (int value in array)
          {
            total += value;
          }
    
          return total;
        }
    
        static int Test2(int[] array)
        {
          int total = 0;
    
          for (int i = 0; i < array.Length; ++i)
          {
            total += array[i];
          }
    
          return total;
        }
      }
    }
    

    Thursday, May 13, 2010 12:07 AM
  • JohnGrove,

    Those articles that you provided are pretty outdated. The msdn one you provided is from Aug. 2001 and shouldn't be thought as relevant IMO. 

    Thursday, May 13, 2010 1:45 AM
  • It is still relevant, yes old, but the For is still "faster", so with regard to that, it still is true. 

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
    
          Int64[] array = new Int64[3000000];
          Stopwatch sw = new Stopwatch();
          List<Employee> list1 = new List<Employee>();
          List<Employee> list2 = new List<Employee>();
    
          //for
          sw.Start();
          for (Int64 i = 0; i < 3000000; i++)
            list1.Add(new Employee{ Name = i.ToString() });    
          sw.Stop();
          Console.WriteLine("For loop took: " + sw.Elapsed);
    
          //reset
          sw.Reset();    
    
          //foreach
          sw.Start();
          foreach (Int64 n in array)
            list2.Add(new Employee { Name = n.ToString() });          
          sw.Stop();
          Console.WriteLine("Foreach loop took: " + sw.Elapsed);
          Console.ReadLine();
        }
      }
    
      class Employee
      {
        public String Name { get; set; }
      }
    }
    

    Every time I tested most anything, it is still faster. Not much. Note the article says this:

    "Foreach is far more readable, and in the future it will become as fast as a For loop for special cases like strings. Unless string manipulation is a real performance hog for you, the slightly messier code may not be worth it."

    The future would be today. (Years later). Almost there, but not quite...


    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Thursday, May 13, 2010 1:50 AM
  • BTW,

    Since there are plenty of VB6 users still out there, we can surmise there are a few .NET 1.1 users out there.


    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Thursday, May 13, 2010 2:02 AM
  • John, when I try your test program I get the following results for a RELEASE build:

    x64 version:

    For loop took: 00:00:01.1705671
    Foreach loop took: 00:00:03.9772620

    x86 version:

    For loop took: 00:00:01.3258012
    Foreach loop took: 00:00:01.4379364

    So for x86, the speed is pretty much identical. Why is it so much slower for the x64 version, I wonder? Something seems wrong there. :)

     

     

    Thursday, May 13, 2010 7:21 AM
  • Even more interestingly, if you change the order of the tests, it appears that the foreach loop is faster than the for loop.

    (This is tested on my work PC rather than my home one, but it's roughly the same.)

    Release AnyCPU (x64) version:

    Foreach loop took: 00:00:01.2796317  <- Faster!
    For loop took: 00:00:01.5298660

    Release x86 version:

    Foreach loop took: 00:00:01.3628608 <- Faster!
    For loop took: 00:00:01.8389110

    So by reordering the loops, we have grossly changed the results! Just goes to show how important timing the code is. Here's the code, by the way. In a minute I'll post some modified test code that runs both the loops in an outer loop serveral times, just to see how that goes.

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
    
          Int64[] array = new Int64[3000000];
          Stopwatch sw = new Stopwatch();
          List<Employee> list1 = new List<Employee>();
          List<Employee> list2 = new List<Employee>();
    
    
          //foreach
          sw.Start();
          foreach (Int64 n in array)
            list1.Add(new Employee
            {
              Name = n.ToString()
            });
          sw.Stop();
    
          Console.WriteLine("Foreach loop took: " + sw.Elapsed);
    
          //for
          sw.Reset();
          sw.Start();
          for (Int64 i = 0; i < 3000000; i++)
            list2.Add(new Employee
            {
              Name = i.ToString()
            });
          sw.Stop();
          Console.WriteLine("For loop took: " + sw.Elapsed);
    
    
          Console.ReadLine();
        }
      }
    
      class Employee
      {
        public String Name
        {
          get;
          set;
        }
      }
    }
    

    Thursday, May 13, 2010 8:58 AM
  • I've just realised that John's test code is not very useful!

    It's comparing doing foreach over a collection with iterating over a range of integers. The foreach is having to fetch each value in an array, while the for is only having to increment an integer.

    Not only that, but the for loop will be adding the string representations of the numbers "0" .. "2999999" to the list, while the foreach loop will be adding the string "0" to the list 3000000 times. So the for loop will be creating MUCH longer strings!

    This is clearly not comparable, so all the results of the stuff to do with this test code is useless, unfortunately.

    Sorry, I should have spotted that earlier!

    I'll post a fixed test in a minute... :)

    Thursday, May 13, 2010 9:05 AM
  • Ok, here's the fixed up test. This test does the 'foreach' before the 'for', but in an outer loop that operates 10 times. (I also tried the code with the 'for' loop before the 'foreach' loop, but it made very little difference so I'm not posting that.)

    x86 results:

    Foreach loop took: 00:00:01.3849790
    For loop took: 00:00:01.4444922
    Foreach loop took: 00:00:01.2752022
    For loop took: 00:00:01.3279171
    Foreach loop took: 00:00:01.3103759
    For loop took: 00:00:01.1856435
    Foreach loop took: 00:00:01.1770661
    For loop took: 00:00:01.6726064
    Foreach loop took: 00:00:01.2382332
    For loop took: 00:00:01.4195517
    Foreach loop took: 00:00:01.1777215
    For loop took: 00:00:01.4811986
    Foreach loop took: 00:00:01.2566612
    For loop took: 00:00:01.3834984
    Foreach loop took: 00:00:01.2073831
    For loop took: 00:00:01.3651546
    Foreach loop took: 00:00:01.4871288
    For loop took: 00:00:01.3471809
    Foreach loop took: 00:00:01.3945828
    For loop took: 00:00:01.3948446

    x64 results:

    Foreach loop took: 00:00:01.1570391
    For loop took: 00:00:01.2675796
    Foreach loop took: 00:00:01.0094637
    For loop took: 00:00:01.6526511
    Foreach loop took: 00:00:01.2749693
    For loop took: 00:00:01.5510075
    Foreach loop took: 00:00:01.4481388
    For loop took: 00:00:01.0773974
    Foreach loop took: 00:00:01.0747262
    For loop took: 00:00:01.0048812
    Foreach loop took: 00:00:01.2402393
    For loop took: 00:00:01.4830517
    Foreach loop took: 00:00:01.2862751
    For loop took: 00:00:01.5580594
    Foreach loop took: 00:00:01.2934815
    For loop took: 00:00:01.2431145
    Foreach loop took: 00:00:01.3157981
    For loop took: 00:00:01.4234528
    Foreach loop took: 00:00:01.1995915
    For loop took: 00:00:01.2863709

    The results are very close, but foreach is edging ahead most of the time.

    Conclusion: As I said, there's not much to call between for and foreach when you use them to access elements of an array. (This is NOT the same as just iterating over a range of integers - the original question was about iterating over arrays.)

    Caveat: Even this isn't a good test - the bulk of the time will be spent creating strings and storing them in a list rather than iterating over an array. Hence any differences in speed are going to be somewhat swamped by the time taken manipulating strings and lists.

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    
    namespace ConsoleApplication1
    {
      class Program
      {
        static void Main(string[] args)
        {
    
          Int64[] array = new Int64[3000000];
          Stopwatch sw = new Stopwatch();
          List<Employee> list1 = new List<Employee>();
          List<Employee> list2 = new List<Employee>();
    
          for (int outer = 0; outer < 10; ++outer)
          {
            list1.Clear();
            list2.Clear();
            sw.Restart();
    
            foreach (Int64 n in array)
              list1.Add(new Employee
              {
                Name = n.ToString()
              });
    
            sw.Stop();
            Console.WriteLine("Foreach loop took: " + sw.Elapsed);
    
            sw.Restart();
    
            for (int i = 0; i < 3000000; i++)
              list2.Add(new Employee
              {
                Name = array[i].ToString()
              });
    
            sw.Stop();
            Console.WriteLine("For loop took: " + sw.Elapsed);
          }
    
          Console.ReadLine();
        }
      }
    
      class Employee
      {
        public String Name
        {
          get;
          set;
        }
      }
    }
    

    Thursday, May 13, 2010 9:15 AM
  • In summary:

    * For loops and foreach loops with arrays are quite similar in speed but "for" is usually faster.
    * Arrays are much faster than lists.
    * The fastest approach in general is to use "for" with an array, if possible.

    We've done a lot of research and timing of real code in this area, since we are writing ECG analysis code in C#, which has to perform many calculations on large arrays. In almost all cases, 'for' has been a little faster than 'foreach'.

    Thursday, May 13, 2010 9:43 AM
  • In summary:

    * For loops and foreach loops with arrays are quite similar in speed but "for" is usually faster.
    * Arrays are much faster than lists.
    * The fastest approach in general is to use "for" with an array, if possible.

    We've done a lot of research and timing of real code in this area, since we are writing ECG analysis code in C#, which has to perform many calculations on large arrays. In almost all cases, 'for' has been a little faster than 'foreach'.


    Isn't that all I have been saying? Agreed that the speed has improved much since .NET 1.1, but that is all I have been saying.

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Thursday, May 13, 2010 1:34 PM
  • Isn't that all I have been saying? Agreed that the speed has improved much since .NET 1.1, but that is all I have been saying.

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com

    No, you said "A for loop is always faster then a foreach", which is not true.

    It's also instructive to point out flaws in timing tests, because invalid timing tests can result in erroneous conclusions.

    Thursday, May 13, 2010 2:09 PM
  • Isn't that all I have been saying? Agreed that the speed has improved much since .NET 1.1, but that is all I have been saying.

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    No, you said "A for loop is always faster then a foreach", which is not true.

    In all my tests this has been true, if on yours it has not, then I stand corrected on this. It was foretold in the link I earlier posted that the foreach would be equal to the for, which seems to "almost" be the case nowadays.

    John Grove - TFD Group, Senior Software Engineer, EI Division, http://www.tfdg.com
    Thursday, May 13, 2010 2:34 PM
  • Aye, well I posted my tests so you can verify it for yourself if you wish. :)
    Thursday, May 13, 2010 2:44 PM
  • Run some speed tests to be sure. Prove it, that a for loop is faster. There is not much difference between the two loop types. What is done inside of the loop makes a bigger difference, which includes what type of collection you are referencing and accessing.

     

    In summary:

    * For loops and foreach loops with arrays are quite similar in speed but "for" is usually faster.
    * Arrays are much faster than lists.
    * The fastest approach in general is to use "for" with an array, if possible.

    We've done a lot of research and timing of real code in this area, since we are writing ECG analysis code in C#, which has to perform many calculations on large arrays. In almost all cases, 'for' has been a little faster than 'foreach'.

     

    My sentiments exactly.  It really depends upon exactly what you are doing inside of the loop.


    Mark the best replies as answers. "Fooling computers since 1971."
    Thursday, May 13, 2010 2:54 PM
    Moderator
  • For loop is faster because while looping it is not required to perform casting and type validation compare to foreach loop.

    but on other side, when you try to get the object using its index, the casting and validation occur - but still not expansive than foreach loop.

     


    Please mark the response as answers if it solves your question or vote as helpful if you find it helpful. My Blog: http://ashishkhandelwal.arkutil.com

    Results can vary depending upon the type of collection you are iterating.
    Mark the best replies as answers. "Fooling computers since 1971."
    Thursday, May 13, 2010 2:56 PM
    Moderator