C-Sharp | Java | Python | Swift | GO | WPF | Ruby | Scala | F# | JavaScript | SQL | PHP | Angular | HTML
They are approximately the same speed. But the foreach loop uses more stack space for local variables. In this comparison, we strive to understand the exact difference in the two loops.
Comparison. First, let's look at the version of the loop that uses the for loop (Method1) and the version that uses the foreach-loop (Method2). Each method sums all the elements in an integer array.
For loop version: Method1 static int Method1(int[] array) { int a = 0; for (int i = 0; i < array.Length; i++) { a += array[i]; } return a; } Foreach loop version: Method2 static int Method2(int[] array) { int a = 0; foreach (int value in array) { a += value; } return a; }
Difference. In .NET 4.0, we see a difference in the IL. The Method1 version uses enough stack space for only two local variables (a and i). The Method2 version uses stack space for four locals (a, value, and two compiler-generated temporaries).
When a method is called in the Common Language Runtime, all of the memory required for the locals is allocated upon the stack. Because this takes place on the stack, this process is fast, but it is not free.
Thus: The foreach-loop will incur a small cost due to its extra two local variables.
Benchmark. Now, let's test these two methods against each other. When testing, try altering the order of the methods such that Method2 is tested before Method1. You will need to paste Method1 and Method2 into the Program class.
Note: The foreach version was slower than the for version. This is because the foreach-version uses more local variable space.
C# program that benchmarks methods using System; using System.Diagnostics; class Program { static void Main() { int[] array = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; Method1(array); Method2(array); var s1 = Stopwatch.StartNew(); const int m = 100000000; for (int i = 0; i < m; i++) { Method1(array); } s1.Stop(); var s2 = Stopwatch.StartNew(); for (int i = 0; i < m; i++) { Method2(array); } s2.Stop(); Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / m).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / m).ToString("0.00 ns")); Console.Read(); } } Output 7.37 ns 8.04 ns
Benchmark 2. The extra local variables in the foreach loop slow down the simple loop. However, it is possible to use those local variables to our advantage. Let's change the loops to have two statements that access the value.
For loop alternate version: Method1 static int Method1(int[] array) { int a = 0; for (int i = 0; i < array.Length; i++) { a += array[i]; a += array[i]; } return a; } Foreach loop alternate version: Method2 static int Method2(int[] array) { int a = 0; foreach (int value in array) { a += value; a += value; } return a; } Results 7.71 ns 7.69 ns
New results. Now, the for loop is slightly slower than the foreach loop. This is because the local variable that stores the value of the element in the array is faster to access than an element in the array.
Summary. In micro-benchmarking, introducing extra local variables with foreach-loops can impact performance. However, if those local variables are reused several times in the loop body, they can lead to a performance improvement.
Thus: The for-loop is faster than the foreach-loop if the array must only be accessed once per iteration.