2011-01-06 80 views
0

大家好哪個LINQ表達更快

在按照我的理解代碼

public class Person 
{ 
    public string Name { get; set; } 
    public uint Age { get; set; } 

    public Person(string name, uint age) 
    { 
     Name = name; 
     Age = age; 
    } 
} 

void Main() 
{ 
    var data = new List<Person>{ new Person("Bill Gates", 55), 
           new Person("Steve Ballmer", 54), 
           new Person("Steve Jobs", 55), 
           new Person("Scott Gu", 35)}; 

    // 1st approach 
    data.Where (x => x.Age > 40).ToList().ForEach(x => x.Age++); 

    // 2nd approach 
    data.ForEach(x => 
        { 
         if (x.Age > 40) 
          x.Age++; 
        }); 

    data.ForEach(x => Console.WriteLine(x));  
} 

第二個方法應該是更快,因爲它的每個項目,遍歷一次,第一種方法是運行2次:

  1. 其中子句
  2. ForEach對where子句中的項目子集。

但內部可能是編譯器會將第一種方法轉換爲第二種方法,它們將具有相同的性能。

任何意見或建議?

我可以做分析一樣的建議,但我想知道是怎麼回事,編譯器級別,如果那些行代碼都是相同的編譯器,或者編譯器會從字面上對待它。

在此先感謝您的幫助。

+2

剖析......做了測量與秒錶,看看什麼是快 – 2011-01-06 18:40:59

+0

你能不只是一次,看看哪個更快? – 2011-01-06 18:41:38

+0

ps。從技術上講,第二種方法(列表中的ForEach)不是Linq,因爲它是List-class上的一個直接方法,它將一個委託作爲參數。 – 2011-01-06 18:42:56

回答

3

我只是跑的代碼,第二運行速度更快:

static void T3() 
     { 
      var data = new List<Person>{ new Person("Bill Gates", 55), 
           new Person("Steve Ballmer", 54), 
           new Person("Steve Jobs", 55), 
           new Person("Scott Gu", 35)}; 

      System.Diagnostics.Stopwatch s1 = new System.Diagnostics.Stopwatch(); 

      s1.Start(); 
      // 1st approach 
      data.Where(x => x.Age > 40).ToList().ForEach(x => x.Age++); 
      s1.Stop(); 

      System.Diagnostics.Stopwatch s2 = new System.Diagnostics.Stopwatch(); 

      s2.Start(); 
      // 2nd approach 
      data.ForEach(x => 
      { 
       if (x.Age > 40) 
        x.Age++; 
      }); 
      s2.Stop(); 

      Console.Write("s1: " + s1.ElapsedTicks + " S2:" + s2.ElapsedTicks); 
      data.ForEach(x => Console.WriteLine(x)); 
     } 

這是可以預料的,因爲第二無需轉換到一個列表,然後運行的foreach方法。

結果:S1:1192 S2:255

1

代碼粘貼到LinqPad(www.linqpad.net)和一次。或者您可以檢查生成的IL代碼以查看編譯器如何處理它。

1

我相信第一個會因爲ToList()緩慢。創建新的數據結構必須相對較慢。

0

如果你感興趣的編譯器如何處理這兩個表達式,爲什麼不編譯每個,然後使用反彙編工具(與Visual Studio捆綁)看生成的代碼?

2

你反對.Where()沒有測量。這兩種方法的真正區別在於.ToList()

第三屆方法:

foreach(Person x in data.Where(x => x.Age > 40)) 
{ 
    x.Age++; 
}