[英]Which LINQ expression is faster
大家好
在下面的代碼中
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));
}
在我的理解中,第二種方法應該更快,因為它會遍歷每個項目一次並且第一種方法運行兩次:
但是在內部,編譯器無論如何都會將第一種方法轉換為第二種方法,並且它們將具有相同的性能。
有什么建議或想法嗎?
我可以像建議的那樣進行概要分析,但是我想了解如果代碼行的內容與編譯器相同,或者編譯器將按字面意義對待,則在編譯器級別上會發生什么。
在此先感謝您的幫助。
我只運行了代碼,第二個運行得更快:
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
您反對.Where()
而不加以衡量。 兩種方法之間的真正區別是.ToList()
。
第三種方法:
foreach(Person x in data.Where(x => x.Age > 40))
{
x.Age++;
}
將代碼粘貼到LinqPad(www.linqpad.net)中並對其計時。 或者,您可以檢查生成的IL代碼,以查看編譯器如何處理它。
我相信第一個會因為ToList()
而變慢。 創建新的數據結構必須相對較慢。
如果您對編譯器如何處理這兩個表達式感興趣,為什么不對它們進行編譯,則使用ildasm工具(與Visual Studio捆綁在一起)查看生成的代碼?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.