为什么使用`foreach`循环数组对象比lambda`ForEach`更快?

14 c# foreach

我在一个数组上工作,我必须循环它.首先,我使用lambdaForEach

Array
.ForEach<int>( array, ( int counter ) => {
    Console.WriteLine( counter ); 
} );
Run Code Online (Sandbox Code Playgroud)

然后我用简单foreach.我发现简单foreach比lambda快得多ForEach,但是当我用通用列表测试它时,ForEach速度比简单快foreach.

为什么在数组对象上循环foreach比lambda快ForEach?更新: 我在阵列上测试

sel*_*ary 4

我稍微编辑了 Keith 的代码 - 在我的机器上foreach执行速度大约是Array.ForEach

class Program
{
    static void Main(string[] args)
    {
        Benchmark(50);
    }

    private static void Benchmark(int iterations)
    {
        int[] list = Enumerable.Range(0, 100000000).ToArray();

        long sum = 0;
        for (int i = 0; i < iterations; i++)
        {
            sum += ArrayForeach(list);
        }

        Console.WriteLine("ForEach " + sum / iterations);

        sum = 0;
        for (int i = 0; i < iterations; i++)
        {
            sum += Foreach(list);
        }

        Console.WriteLine("foreach " + sum / iterations);
    }

    private static long Foreach(int[] list)
    {
        long total = 0;
        var stopWatch = Stopwatch.StartNew();
        foreach (var i in list)
        {
            total += i;
        }
        stopWatch.Stop();
        return stopWatch.ElapsedTicks;
    }

    private static long ArrayForeach(int[] list)
    {
        long total = 0;
        var stopWatch = Stopwatch.StartNew();
        Array.ForEach(list, x => total += x);
        stopWatch.Stop();
        return stopWatch.ElapsedTicks;
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上(可能运行与其他机器不同的 CLR)它生成(在发行版中):

ForEach 695910  
foreach 123852  
Run Code Online (Sandbox Code Playgroud)

在调试中:

ForEach 941030
foreach 845443
Run Code Online (Sandbox Code Playgroud)
  • 它表明foreach享受一些编译器优化,我猜主要是在访问内存中的列表。
  • 在调试中,看起来像是运行 lambda 的开销,并且传递数字(按值)是造成差异的原因。

我建议有更多时间的人可以用 Reflector 看看...