Статические конструкторы вызывают производительность наверху?

Недавно читайте в статье о dotnetpearls.com, здесь говоря, что статические ctors берут значительное количество хита производительности.

Не мог понять почему?

15
задан Peter G. 15 November 2011 в 07:30
поделиться

3 ответа

Я думаю, что «существенный» - это преувеличение в большинстве вариантов использования.

Наличие статического конструктора (даже если он ничего не делает) влияет на время инициализации типа из-за наличия / отсутствия флага beforefieldinit . Если у вас есть статический конструктор, существуют более строгие гарантии относительно времени.

Для большей части кода я бы предположил, что это не имеет большого значения, но если вы зацикливаетесь и обращаетесь к статическому члену класса, может. Лично я бы не стал особо беспокоиться об этом - если у вас есть подозрение, что это актуально для вашего реального приложения, то протестируйте его, а не гадайте. Микробенчмарки здесь, скорее всего, преувеличивают эффект.

Стоит отметить, что .NET 4 ведет себя несколько иначе, чем предыдущие версии , когда дело доходит до инициализации типа, поэтому любые тесты должны действительно показывать разные версии, чтобы быть актуальными.

18
ответ дан 1 December 2019 в 01:38
поделиться

Ну я просто повторил его тест.

Для 1000000000 итераций с DEBUG сборкой я получил:

  • 4s для его статического класса со статическим конструктором
  • 3.6s для того же класса с закомментированным статическим конструктором
  • 2.9s для класса нестатического (и создающего экземпляр перед итерации) либо со статическим конструктором или нет

То же самое со сборкой RELEASE does подчеркивает разницу:

  • Статический класс со статическим конструктором: 4046.875ms
  • Статический класс без статического конструктора: 484.375ms
  • Экземпляр со статическим конструктором: 484.375ms
  • Экземпляр без статического конструктора: 484.375ms
11
ответ дан 1 December 2019 в 01:38
поделиться

CLR обеспечивает довольно надежную гарантию выполнения статических конструкторов, она обещает вызвать их только один раз и до того, как сможет работать любой метод в классе. Эту гарантию довольно сложно реализовать, когда есть несколько потоков, использующих класс.

Заглянув в исходный код CLR для SSCLI20, я вижу довольно большой фрагмент кода, предназначенный для предоставления этой гарантии. Он поддерживает список работающих статических конструкторов, защищенных глобальной блокировкой. Как только он получает запись в этом списке, он переключается на специфичную для класса блокировку, которая гарантирует, что конструктор не может быть запущен двумя потоками. Двойная проверка блокировки по биту состояния, который указывает, что конструктор уже запущен. Множество непостижимого кода, обеспечивающего гарантии исключений.

Ну, этот код не предоставляется бесплатно. Добавьте это ко времени выполнения самого cctor, и вы увидите некоторые накладные расходы. Как всегда, не позволяйте этому стеснять ваш стиль, эта гарантия также очень хороша, и вы бы не захотели предоставить ее сами. И измерьте, прежде чем исправлять.

6
ответ дан 1 December 2019 в 01:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: