Three different implementations of finding the sum of an IEnumerable < int> source are given below along with the time taken when the source has 10,000 integers.
source.Aggregate(0, (result, element) => result + element);
takes 3 ms
source.Sum(c => c);
takes 12 ms
source.Sum();
takes 1 ms
I am wondering why the second implementation is four times more expensive than the first one. Shouldn't it be same as the third implementation.
Note: My computer is running .Net 4.5 RC, so it's possible that my results are affected by this.
Measuring the time it takes to execute a method just once is usually not very useful. It can be easily dominated by things like JIT compilation, which are not actual bottlenecks in real code. Because of this, I measured executing each method 100× (in Release mode without debugger attached). My results are:
Aggregate()
: 9 msSum(lambda)
: 12 msSum()
: 6 msThe fact that
Sum()
is the fastest is not surprising: it contains a simple loop without any delegate invocations, which is really fast. The difference betweenSum(lambda)
andAggregate()
is not nearly as prominent as what you measured, but it's still there. What could be the reason for it? Let's look at decompiled code for the two methods:As you can see,
Aggregate()
uses a loop butSum(lambda)
usesSelect()
, which in turn uses an iterator. And using an iterator means there is some overhead: creating the iterator object and (probably more importantly) one more method invocation for each item.Let's verify that using
Select()
is actually the reason by writing our ownSum(lambda)
twice, once usingSelect()
, which should behave the same asSum(lambda)
from the framework, and once without usingSelect()
:My measurements confirm what I thought:
SlowSum(lambda)
: 12 msFastSum(lambda)
: 9 ms