Автор: Sergey Teplyakov

В предыдущей заметке я спросил у многоуважаемой аудитории, что мне делать с англоязычными постами. Мнения разделились: часть аудитории согласились с публикацией здесь лишь анонсов, а другая часть посоветовала переводить. Я, правда, хотел бы переводить, но не уверен, что у меня хватит запала.

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

Ну а теперь, к теме сегодняшней публикации.

Я уже несколько раз затрагивал вопрос реализации одной довольно простой возможности языка C# - ограничения обобщений new(), что она, дескать, реализована через Activator.CreateInstance (да и то, не всегда,), подробности в оригинале!).

Проблем у этого аспекта аж две (что и делает new() ограничение выдающейся дырявой абстракцией): низкая производительность и хитрость с обработкой исключений.

Так вот, у нас на проекте, активное использование new T() весьма быстро вылезло в профилировщике, было починено с весьма заметным приростом end-to-end времени исполнения. Там мы прикрутили простое решение на основе деревьев выражения и про это забыли.

А не так давно на ru.stackoverflow.com был задан вопрос по поводу кодогенерации и примеров ее применения, что дало дополнительную почву для размышлений на эту же тему. В результате были перекопаны следующие вещи, чтобы добиться эффективности кастомного активатора равных вызову делегата вида () =>, new CustomNode():

  • Как именно реализован активатор (с его кэшами, багами в кэше, и довольно необычным способом создания пустого экземпляра).
  • Как именно компилируются деревья выражений и почему получаемый в результате делегат медленнее рукописного.
  • Как скомпилировать выражение в динамический метод руками.
  • Как внутри устроены обобщения и почему для ссылочных типов вызов одного обобщенного метода из другого имеет ненулевые накладные расходы.

В результате работы над постом, была получена обобщенная фабрика, эффективность которой равна эффективности делегата, создающего конкретный экземпляр. Что, как мне кажется, весьма интересный результат,)

Понятное дело, что подробности по ссылке: Dissecting the new() constraint in C#: a perfect example of a leaky abstraction.

З.Ы. Я надеюсь, что читать такое введение интереснее, чем просто увидеть ссылку.

З.Ы.Ы. Пожелания, предложения и все такое, всячески приветствуется.

Помогла статья? Оцените её!
0 из 5. Общее количество голосов - 0
 

You have no rights to post comments

Дмитрий Крикунов

Публикую статьи, обучающие курсы и новости по программированию: алгоритмам, языкам (С++, Java), параллельному программированию, паттернам и библиотекам (Qt, boost).