.NET Generics under the hood and a JITter bug for dessert

Generics – старая и хорошо известная парадигма программирования. Все мы знаем, как их использовать и какие преимущества они нам дают. Но знаете ли вы как они работают изнутри? Думаете, что тут замешена магия? Есть внутренне чувство, что все на костылях? Интересно, почему один и тот же метод может работать в 3-5 раз медленнее? Например, вот этот:

  new DerivedClass().Run(); // 3-5x slower
  new BaseClass<object>().Run();
  ...
  public class BaseClass<T> {
    private List<T> _list = new List<T>();
    public BaseClass() {
      foreach (var _ in _list) {}
    }
    public void Run() {
      for (var i = 0; i < 8000000; i++)
        if (_list.Any(_ => true)) return;
    }
  }

Попробуем вместе в этом разобраться. Доклад про то, как это все работает изнутри. Вспомним про .NET Memory Layout, позапускаем WinDbg, посмотрим как .NET generics устроены изнутри, какие оптимизации CLR предпринимает, чтобы они были быстрыми, и, что самое интересное, чаще всего такими же быстрыми, как и обычные методы.

Будет десерт – баг в Джиттере! Только хардкор! Еще больше хардкора в обсуждениях. Приходите те, кто интересуется внутренностями .NET, будет интересно

Александр Никитин

Александр Никитин

«Боевой инженер» в компании Adform, работает на темной стороне серверов. Специализируется на распределенных high-load и low-latency системах. Почти достиг совершенства в создании несовершенных вещей. Имел насыщенные отношения с .NET, но сбежал к JVM как только увидел исходники, и вот уже год как со Scala. Но ему все еще снится .NET, и иногда эти сны приятны.

×