簡體   English   中英

為什么用`foreach`循環數組對象比lambda`ForEach`更快?

[英]Why loop on array object with `foreach` is faster than lambda `ForEach`?

我在一個數組上工作,我必須循環它。 首先,我使用lambda ForEach

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

然后我用簡單的foreach 我發現簡單的foreach比lambda ForEach快得多,但是當我使用泛型列表進行測試時, ForEach比簡單的foreach更快。

為什么用foreach循環數組對象比lambda ForEach更快? 更新: 我在陣列上測試

我在測試中發現lambda更快。 復制粘貼MSDN秒表代碼並用兩個版本的迭代列表進行裝飾....(我還改變了首先測試的順序,我得到了相同的時間)。 使用lambda的基於Linq的迭代變得更快。

Lambda  00:00:00.49
foreach 00:00:00.58

和代碼..

var list = Enumerable.Range(0, 100000000).ToArray();
        var total = 0;
        var stopWatch = new Stopwatch();
        stopWatch.Start();
        Array.ForEach(list, x => total += x);

        stopWatch.Stop();
        TimeSpan ts = stopWatch.Elapsed;
        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10);
        Console.WriteLine("RunTime " + elapsedTime);


        stopWatch = new Stopwatch();
        stopWatch.Start();
        foreach (var i in list)
        {
            total += i;
        }      
        stopWatch.Stop();
        // Get the elapsed time as a TimeSpan value.
        ts = stopWatch.Elapsed;

        // Format and display the TimeSpan value. 
        elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10);
        Console.WriteLine("RunTime " + elapsedTime);            

我稍微編輯了Keith的代碼 - 在我的機器上, foreach執行速度比Array.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不同的CLR),它生成(在Release中):

ForEach 695910  
foreach 123852  

在調試中:

ForEach 941030
foreach 845443
  • 它表明foreach享有一些編譯器優化,我猜主要是在訪問內存中的列表。
  • 在Debug中,它看起來像運行lambda的開銷,並且傳遞數字(按值)是造成差異的原因。

我建議有更多時間的人看看Reflector ...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM