2013-05-27 56 views
14

我在一個數組上工作,我必須循環它。首先,我用的λForEach爲什麼使用`foreach`循環數組對象快於lambda`ForEach`?

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

,然後我用簡單的foreach。 我發現簡單的foreach比lambda ForEach快,但是當我用通用列表測試它時,ForEach比簡單的foreach快。

爲什麼在foreach的數組對象上循環比lambda ForEach更快? 更新: 我在陣列上測試

+0

件事,你叫實際上拉姆達的foreach落實懶惰的評價,所以有很多額外的代碼。 – vittore

+14

顯示你的測試用例。 –

+1

我發現對面在我的測試 –

回答

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享受一些編譯器優化,我想主要是在內存訪問列表。
  • 在調試中,它看起來像運行lambda的開銷,並通過數值(按值)負責差異。

我建議別人有更多的時間採取與反射看看...

4

我在測試中發現lambda更快。複製粘貼MSDN秒錶代碼,並用迭代List的兩個版本來裝飾它。(我也改變了首先進行測試的順序,並且獲得了相同的計時)。基於Linq的lambda迭代更快。

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);    
+0

使用拉姆達爲速度更快的贏家,但拉姆達仍然贏得 –

+0

有點 –

+1

多少更快?介紹更新後的文章中的詳細數字? – David