Перечисление через интерфейс - потеря производительности

У меня был небольшой спор (который был очень близок к священной войне :) ) с моим коллегой по поводу производительности доступа к списку через индексы VSчерез счетчик. Чтобы оперировать некоторыми фактами, я написал следующий тест:

   static void Main(string[] args)
    {
        const int count = 10000000;

        var stopwatch = new Stopwatch();

        var list = new List<int>(count);

        var rnd = new Random();

        for (int i = 0; i < count; i++)
        {
            list.Add( rnd.Next());
        }

        const int repeat = 20;

        double indeces = 0;
        double forEach = 0;

        for (int iteration = 0; iteration < repeat; iteration++)
        {
            stopwatch.Restart();
            long tmp = 0;
            for (int i = 0; i < count; i++)
            {                    
                tmp += list[i];
            }

            indeces += stopwatch.Elapsed.TotalSeconds;
            stopwatch.Restart();
            foreach (var integer in list)
            {            
                tmp += integer;
            }

            forEach += stopwatch.Elapsed.TotalSeconds;
        }

        Console.WriteLine(indeces /repeat);
        Console.WriteLine(forEach /repeat);

    }

На самом деле он просто обращается к элементам.

Как я и ожидал, доступ к индексу оказался быстрее. Вот результаты сборки релиза на моей машине:

    0.0347//index access
    0.0737//enumerating

Однако я решил немного изменить тест:

        //the same as before
        ...
        IEnumerable<int> listAsEnumerable = list;
        //the same as before
        ...
        foreach (var integer in listAsEnumerable)
        {                
            tmp += integer;
        }
        ...

И теперь вывод был следующим:

    0.0321//index access
    0.1246//enumerating (2x slower!)

Если мы перечисляем тот же список через интерфейс, производительность В 2 разамедленнее!

Почему это* происходит?

thisозначает "перечисление через интерфейс в 2 раза медленнее, чем перечисление фактического списка".

Я предполагаю, что среда выполнения использует разные Enumerators: список в первом тесте и общий во втором тесте.

14
задан undefined 18 May 2012 в 15:45
поделиться