Нижеприведенный код проверяет производительность трех разных способов выполнения одного и того же решения.
public static void Main(string[] args)
{
// for loop
{
Stopwatch sw = Stopwatch.StartNew();
int accumulator = 0;
for (int i = 1; i <= 100000000; ++i)
{
accumulator += i;
}
sw.Stop();
Console.WriteLine("time = {0}; result = {1}", sw.ElapsedMilliseconds, accumulator);
}
//Enumerable.Range
{
Stopwatch sw = Stopwatch.StartNew();
var ret = Enumerable.Range(1, 100000000).Aggregate(0, (accumulator, n) => accumulator + n);
sw.Stop();
Console.WriteLine("time = {0}; result = {1}", sw.ElapsedMilliseconds, ret);
}
//self-made IEnumerable<int>
{
Stopwatch sw = Stopwatch.StartNew();
var ret = GetIntRange(1, 100000000).Aggregate(0, (accumulator, n) => accumulator + n);
sw.Stop();
Console.WriteLine("time = {0}; result = {1}", sw.ElapsedMilliseconds, ret);
}
}
private static IEnumerable<int> GetIntRange(int start, int count)
{
int end = start + count;
for (int i = start; i < end; ++i)
{
yield return i;
}
}
}
Результаты:
time = 306; result = 987459712
time = 1301; result = 987459712
time = 2860; result = 987459712
Неудивительно, что цикл "for" быстрее, чем два других решения, потому что Enumerable.Aggregate принимает больше вызовов методов. Однако меня действительно удивляет, что "Enumerable.Range" быстрее, чем "самодельный IEnumerable". Я думал, что Enumerable.Range будет иметь больше накладных расходов, чем простой метод GetIntRange.
Каковы возможные причины этого?