gpt4 book ai didi

c# - LINQ 中的聚合与求和性能

转载 作者:IT王子 更新时间:2023-10-29 04:10:21 28 4
gpt4 key购买 nike

下面给出了查找IEnumerable 总和的三种不同实现方式,以及当源具有 10,000 个整数时所花费的时间。

source.Aggregate(0, (result, element) => result + element);  

需要 3 毫秒

source.Sum(c => c);

需要 12 毫秒

source.Sum();

需要 1 毫秒

我想知道为什么第二个实现比第一个实现贵四倍。不应该和第三种实现一样吗。

最佳答案

注意:我的电脑运行的是 .Net 4.5 RC,所以我的结果可能会受到影响。

测量一个方法只执行一次所花费的时间通常不是很有用。它很容易被 JIT 编译之类的东西所控制,这在实际代码中并不是真正的瓶颈。因此,我测量了每个方法执行 100 次(在没有附加调试器的 Release模式下)。我的结果是:

  • 聚合():9 毫秒
  • Sum(lambda):12 毫秒
  • Sum():6 毫秒

Sum() 是最快的这一事实不足为奇:它包含一个没有任何委托(delegate)调用的简单循环,速度非常快。 Sum(lambda)Aggregate() 之间的差异并不像您所测量的那么明显,但它仍然存在。可能是什么原因呢?让我们看看这两种方法的反编译代码:

public static TAccumulate Aggregate<TSource, TAccumulate>(this IEnumerable<TSource> source, TAccumulate seed, Func<TAccumulate, TSource, TAccumulate> func)
{
if (source == null)
throw Error.ArgumentNull("source");
if (func == null)
throw Error.ArgumentNull("func");

TAccumulate local = seed;
foreach (TSource local2 in source)
local = func(local, local2);
return local;
}

public static int Sum<TSource>(this IEnumerable<TSource> source, Func<TSource, int> selector)
{
return source.Select<TSource, int>(selector).Sum();
}

如您所见,Aggregate() 使用循环,但 Sum(lambda) 使用 Select(),后者又使用一个循环迭代器。使用迭代器意味着会产生一些开销:创建迭代器对象和(可能更重要的是)为每个项目再调用一次方法。

让我们通过编写我们自己的 Sum(lambda) 两次来验证使用 Select() 实际上是原因,一次使用 Select() ,其行为应与框架中的 Sum(lambda) 相同,并且一次不使用 Select():

public static int SlowSum<T>(this IEnumerable<T> source, Func<T, int> selector)
{
return source.Select(selector).Sum();
}

public static int FastSum<T>(this IEnumerable<T> source, Func<T, int> selector)
{
if (source == null)
throw new ArgumentNullException("source");
if (selector == null)
throw new ArgumentNullException("selector");

int num = 0;
foreach (T item in source)
num += selector(item);
return num;
}

我的测量证实了我的想法:

  • SlowSum(lambda):12 毫秒
  • FastSum(lambda):9 毫秒

关于c# - LINQ 中的聚合与求和性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11030109/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com