В предыдущей заметке я спросил у многоуважаемой аудитории, что мне делать с англоязычными постами. Мнения разделились: часть аудитории согласились с публикацией здесь лишь анонсов, а другая часть посоветовала переводить. Я, правда, хотел бы переводить, но не уверен, что у меня хватит запала.
Поэтому я решил, что вместо перевода или простых ссылок, я буду делать здесь довольно развернутые анонсы, с превьюхой англоязычного поста. Так что эти публикации можно будет рассматривать в виде таких себе «трейлеров», да и обсуждать здесь на великом и могучем.
Ну а теперь, к теме сегодняшней публикации.
Я уже несколько раз затрагивал вопрос реализации одной довольно простой возможности языка 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.
З.Ы. Я надеюсь, что читать такое введение интереснее, чем просто увидеть ссылку.
З.Ы.Ы. Пожелания, предложения и все такое, всячески приветствуется.