Почему Enumerable.Range быстрее, чем цикл прямого выхода?

Приведенный ниже код проверяет производительность трех разных способов сделать одно и то же решение.

    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.

Каковы возможные причины этого?

Ответы на вопрос(4)

Ваш ответ на вопрос