
Loop performance is important. How can you improve the iteration performance of a foreach loop construct in the C# programming language? While the foreach loop is often less efficient than a simple for loop, there are cases where improving the efficiency of a foreach loop is useful.
ForeachThis C# optimization article speeds up a foreach-loop over a field.
This program uses two foreach loops with slightly different patterns. The first method (Method1) uses the foreach loop that access the instance field _values directly in the iteration expression. The second method (Method2) uses the foreach loop that stores the instance field into a local variable reference. Then it uses that local variable in the iteration expression.
Because the field's address must be resolved each time it is accessed, the Method1 version is slower. It includes an extra level of indirection on each iteration.
Program that tests foreach loop performance [C#]
using System;
using System.Diagnostics;
class Program
{
const int _max = 100000000;
static void Main()
{
Program program = new Program();
var s1 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
program.Method1();
}
s1.Stop();
var s2 = Stopwatch.StartNew();
for (int i = 0; i < _max; i++)
{
program.Method2();
}
s2.Stop();
Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000 * 1000) /
_max).ToString("0.00 ns"));
Console.Read();
}
int[] _values = { 1, 2, 3 };
int Method1()
{
// Access the field directly in the foreach expression.
int result = 0;
foreach (int value in this._values)
{
result += value;
}
return result;
}
int Method2()
{
// Store the field into a local variable and then iterate.
int result = 0;
var values = this._values;
foreach (int value in values)
{
result += value;
}
return result;
}
}
Output
3.86 ns
2.26 ns
Results. In the output section, we see that the version that uses the field reference inside the foreach loop requires 1.7 times more clock cycles for execution. This indicates that storing all variables in the foreach loop iteration expression as local variables is a measurable optimization.

Although the performance benefit to this local variable foreach loop optimization may seem small, it does influence execution time. And while the optimization may not be directly practical, it illustrates in a tangible way how the memory model in the .NET Framework works: fields introduce an extra level of indirection at every access.
Intermediate Language Loop Constructs