2011-01-06 82 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++; 
}