【发布时间】:2016-12-02 06:17:32
【问题描述】:
简短的问题:为什么 LINQ 比通过 foreach 循环进行聚合操作慢?
说明 -
我正在尝试优化一些旧代码,虽然 LINQ 查询在整个代码中被广泛使用,但像在 Enumerable 中求和数字这样的琐碎操作是使用循环完成的。
所以,我运行了一个小测试来比较这两种方法的性能。 下面是使用 LINQ 的 .Sum() 方法和使用 foreach 循环并手动总结每个出现次数的 1000 个可枚举长的数字总和的代码。
List<Double> numbers = new List<Double>();
Double[] sums1 = new Double[1000];
Double[] sums2 = new Double[1000];
for (int i = 0; i < 1000; i++)
{
numbers.Add(i * i);
}
Int64 startTime1 = Stopwatch.GetTimestamp();
for (int i = 0; i < 1000; i++)
{
Double sum = 0;
sum = numbers.Sum();
sums1[i] = sum;
}
Int64 endTime1 = Stopwatch.GetTimestamp();
Int64 startTime2 = Stopwatch.GetTimestamp();
for (int i = 0; i < 1000; i++)
{
Double sum = 0;
foreach (Double number in numbers)
{
sum += number;
}
sums2[i] = sum;
}
Int64 endTime2 = Stopwatch.GetTimestamp();
Console.WriteLine("LINQ. Start = {0}, End = {1}: Diff = {2}", startTime1, endTime1, endTime1 - startTime1);
Console.WriteLine("ForEach. Start = {0}, End = {1}: Diff = {2}", startTime2, endTime2, endTime2 - startTime2);
我运行了这个测试几(十)次,结果是:
LINQ. Start = 117385428996, End = 117385462197: Diff = 33201
Foreach. Start = 117385462203, End = 117385476329: Diff = 14126
LINQ. Start = 117385478555, End = 117385499802: Diff = 21247
Foreach. Start = 117385499808, End = 117385520756: Diff = 20948
LINQ. Start = 117385521426, End = 117385546256: Diff = 24830
Foreach. Start = 117385546260, End = 117385567052: Diff = 20792
LINQ. Start = 117385572791, End = 117385602149: Diff = 29358
Foreach. Start = 117385602156, End = 117385622367: Diff = 20211
LINQ. Start = 117385623153, End = 117385652563: Diff = 29410
Foreach. Start = 117385652568, End = 117385673733: Diff = 21165
LINQ. Start = 117385674403, End = 117385705028: Diff = 30625
Foreach. Start = 117385705035, End = 117385725552: Diff = 20517
LINQ. Start = 117385726094, End = 117385753161: Diff = 27067
Foreach. Start = 117385753166, End = 117385771824: Diff = 18658
LINQ. Start = 117385772341, End = 117385793726: Diff = 21385
Foreach. Start = 117385793733, End = 117385811332: Diff = 17599
LINQ. Start = 117385811768, End = 117385837204: Diff = 25436
Foreach. Start = 117385837209, End = 117385852670: Diff = 15461
LINQ. Start = 117385853003, End = 117385874410: Diff = 21407
Foreach. Start = 117385874416, End = 117385891874: Diff = 17458
请注意,foreach 循环总是执行得更好。这可能是什么原因?
编辑:answer 到这个question 有很多很好的信息,说明为什么与常规内联操作相比性能可能会很差。但我无法看到它与这里的确切关系。
【问题讨论】:
-
LINQ performance FAQ的可能重复
-
我用
for (int x = 0; x < numbers.Count; x++)添加了一个外观,它在LINQ和foreach之间 -
顺便说一句。你编码日志
ForEach,结果有Foreach。魔术;) -
当然,您在发布模式下运行此测试并进行了优化,不是吗?
-
Linq 正在执行动态解析,而 for 循环正在使用固定的编译代码。动态解决方案总是比经过优化的编译代码慢。
标签: c# performance linq foreach