Интересное падение производительности
От: Димчанский Литва http://dimchansky.github.io/
Дата: 28.11.14 08:09
Оценка: 80 (10)
Коллеги наткнулись на интересное падение производительности. Подняли тему на stackoverflow.
Наткнулись в реальном коде, им удалось воссоздать минимальный пример.

Есть generic класс
public class BaseClass<T>
{
    private List<T> _list = new List<T>();

    public BaseClass()
    {
    // если убрать эту строку из конструктора, то падения производительности в Run не происходит
        Enumerable.Empty<T>();
        // или Enumerable.Repeat(new T(), 10);
        // или даже new T();
        // или foreach (var item in _list) {}
        // или что-либо, что ссылается на тип T
    }

    public void Run()
    {
        for (var i = 0; i < 8000000; i++)
        {
            _list.Any();
        }
    }
}


создается наследник

public class DerivedClass : BaseClass<object>
{
}


Далее делают замеры метода Run из обоих классов. Предвосхищая вопросы о методах замера, они пробовали и с разогревом и меняя местами строки Measure.
Компилировали в Release-режиме под .NET 4.5.

public class Program
{
    public static void Main()
    {
        Measure(new DerivedClass());
        Measure(new BaseClass<object>());
    }

    private static void Measure(BaseClass<object> baseClass)
    {
        var sw = Stopwatch.StartNew();
        baseClass.Run();
        sw.Stop();
        Console.WriteLine(sw.ElapsedMilliseconds);
    }
}


Вызов метода Run в наследованном классе DerivedClass в 4 раза медленнее, чем в BaseClass<object>.
Есть мысли, почему так может быть?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.