Улучшение отражения производительности - какие альтернативы мне следует рассмотреть? - PullRequest
18 голосов
/ 22 июня 2009

Мне нужно динамически установить значения для группы или свойства объекта, назвать его объектом передачи.

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

Есть ли альтернативы? Если да, то есть ли примеры реализации, на которые я мог бы взглянуть?

Ответы [ 6 ]

27 голосов
/ 22 июня 2009

Используйте Delegate.CreateDelegate, чтобы превратить MethodInfo в строго типизированный делегат. Это может улучшить производительность массово . У меня есть сообщение в блоге об этом с примером кода. Обратите внимание, что это поможет, только если вам нужно установить одни и те же свойства несколько раз - в основном это означает, что большая часть проверки типов выполняется один раз при создании делегата, а не при каждом вызове.

Марк Грэвелл имеет проект HyperPropertyDescriptor , который обеспечивает еще лучшую производительность, но вводит дополнительную зависимость. Этот проект стал отправной точкой для более современного Fast Member ( github ). Как правило, вы используете Fast Member вместо HyperProperty.

6 голосов
/ 22 июня 2009

В .NET 4.0 (бета) вы можете сделать это с обновленными деревьями выражений, используя Expression.Block и Expression.Assign - затем скомпилировать это с типизированным делегатом; работа выполнена.

В .NET 2.0 и выше (как упоминал Джон) HyperDescriptor является разумным вариантом - он работает как пользовательская реализация PropertyDescriptor, поэтому вы просто делаете код, подобный:

// store this collection for optimum performance
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(
    typeof(SomeType));
props["Name"].SetValue(obj, newName);
props["DateOfBirth"].SetValue(obj, newDoB);

Это все еще имеет небольшой бокс, но на самом деле это не узкое место.

3 голосов
/ 22 июня 2009

Отражение может быть невероятно быстрым , если вы все сделаете правильно (конечно, не так быстро, как статический код).

Поиск свойства-установщика идет медленно. Вызов делегата происходит быстро.

Вам необходимо получить и кэшировать Delegate объектов для каждого установщика свойств для каждого типа DTO. Это медленная часть, но это одноразовый хит. Затем вы можете Invoke каждый из кэшированных делегатов для установщиков свойств данного типа DTO, передавая объект DTO и новое значение свойства, но эта часть будет очень быстрой.

0 голосов
/ 22 июня 2009

Отражение получило плохую репутацию из Java, где она (или, по крайней мере, раньше) была очень медленной. Это не так в .net, поэтому я не понимаю, что вы возражаете против его использования. Также я согласен с Рексом: нельзя сказать, что что-то имеет плохую производительность без фактического измерения.

0 голосов
/ 22 июня 2009

Вы можете использовать облегченную генерацию кода. Вот несколько статей:

0 голосов
/ 22 июня 2009

Установили ли вы с уверенностью, что использование отражения слишком медленное? Хотя отражение в .NET не так быстро , как в статическом коде, оно все равно чрезвычайно быстро. Вы должны писать код как можно проще - даже если он использует отражение - и возвращаться для оптимизации можно только в том случае, если вы заметили проблемы с производительностью и изолировали их от использования отражения. В большинстве случаев у вас не будет проблем. Отражение используется во всех видах кода, чувствительного к производительности, например ASP.NET MVC.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...