14

私は配列に取り組んでおり、それをループする必要があります。まず、ラムダを使用しますForEach

Array
.ForEach<int>( array, ( int counter ) => {
    Console.WriteLine( counter ); 
} );

そして、 simple を使用しますforeachforeachsimpleは lambda よりも非常に高速であることがわかりましたForEachが、一般的なリストでテストするとForEach、 simple よりも高速ですforeach

配列オブジェクトのループforeachが lambda よりも速いのはなぜForEachですか? 更新: アレイでテストします

4

2 に答える 2

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;
    }
}

私のマシン (他のマシンとは異なる CLR を実行している可能性があります) では、(リリースで) 以下が生成されます。

ForEach 695910  
foreach 123852  

デバッグ中:

ForEach 941030
foreach 845443
  • foreach主にメモリ内のリストにアクセスする際に、いくつかのコンパイラの最適化を楽しんでいることを示しています。
  • デバッグでは、ラムダを実行するオーバーヘッドのように見え、数値を (値で) 渡すことが違いの原因です。

もっと時間がある人は、Reflector を試してみることをお勧めします...

于 2013-05-27T06:00:08.167 に答える