Почему использование Func<> намного быстрее, чем использование нового ограничения ()для создателя универсальной последовательности

Рассмотрим следующий код...

В моих тестах для РЕЛИЗА (не отлаживать! )Сборка x86 на ПК с Windows 7 x64 (Intel i7 3GHz )Я получил следующие результаты:

CreateSequence() with new() took 00:00:00.9158071
CreateSequence() with creator() took 00:00:00.1383482

CreateSequence() with new() took 00:00:00.9198317
CreateSequence() with creator() took 00:00:00.1372920

CreateSequence() with new() took 00:00:00.9340462
CreateSequence() with creator() took 00:00:00.1447375

CreateSequence() with new() took 00:00:00.9344077
CreateSequence() with creator() took 00:00:00.1365162

Кажется, что использование Func<> для определения делегата для создания новых объектов более чем в 6 раз быстрее чем прямой вызов "new T ()".

Я нахожу это несколько неожиданным... Я думаю, это из-за некоторого встраивания, сделанного Jitter, но я бы подумал, что он сможет так же оптимизировать "новый T ()".

Есть ли у кого-нибудь объяснение этому?

Может быть, я ошибаюсь. (Я рассматривал эффект, который может иметь сборщик мусора, но изменение кода и добавление GC.Collect ()и т. д. существенно не меняет результаты ).

В любом случае, вот код:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApplication6
{
    class Program
    {
        static void Main(string[] args)
        {
            Stopwatch sw = new Stopwatch();

            int repeats =    100;
            int count   = 100000;

            for (int outer = 0; outer < 4; ++outer)
            {
                sw.Restart();

                for (int inner = 0; inner < repeats; ++inner)
                {
                    CreateSequence<object>(count).Count();
                }

                Console.WriteLine("CreateSequence() with new() took " + sw.Elapsed);
                sw.Restart();

                for (int inner = 0; inner < repeats; ++inner)
                {
                    CreateSequence(count, () => new object()).Count();
                }

                Console.WriteLine("CreateSequence() with creator() took " + sw.Elapsed);
                Console.WriteLine();
            }
        }

        public static IEnumerable<T> CreateSequence<T>(int n) where T: new()
        {
            for (int i = 0; i < n; ++i)
            {
                yield return new T();
            }
        }

        public static IEnumerable<T> CreateSequence<T>(int n, Func<T> creator)
        {
            for (int i = 0; i < n; ++i)
            {
                yield return creator();
            }
        }
    }
}
13
задан Matthew Watson 16 April 2012 в 12:32
поделиться