Улучшение отражения производительности - какие альтернативы мне следует рассмотреть?
Мне нужно динамически устанавливать значения для группы или свойства объекта, называть его объектом передачи.
Будет создано достаточное количество этих объектов передачи, и их свойства будут установлены в короткий промежуток времени. Я хочу избежать использования отражения.
Есть ли альтернативы? Если да, то есть ли примеры реализации, на которые я мог бы взглянуть?
Ответы
Ответ 1
Используйте Delegate.CreateDelegate
чтобы превратить MethodInfo
в строго типизированный делегат. Это может значительно повысить производительность. У меня есть запись в блоге об этом с примером кода. Обратите внимание, что это поможет только в том случае, если вам нужно установить одни и те же свойства несколько раз - в основном это означает, что большая часть проверки типов выполняется один раз при создании делегата, а не при каждом вызове.
У Марка Гравелла есть проект HyperPropertyDescriptor, который обеспечивает еще лучшую производительность, но вносит дополнительную зависимость. Этот проект стал отправной точкой для более современного Fast Member (github). В общем, вы бы использовали Fast Member поверх HyperProperty.
Ответ 2
В .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
Отражение может быть невероятно быстрым, если вы делаете это правильно (конечно, не так быстро, как статический код).
Поиск установки свойств выполняется медленно. Вызов делегата выполняется быстро.
Вам нужно получить и кэшировать объекты Delegate
для каждого свойства-установщика для каждого типа DTO. Это медленная часть, но это одноразовый удар. Затем вы можете Invoke
каждого из кэшированных делегатов для свойств-свойств заданного типа DTO, передавая объект DTO и новое значение свойства, но эта часть будет очень быстрой.
Ответ 4
У вас есть уверенность в том, что использование рефлексии слишком медленное? Хотя отражение в .NET не так быстро, как статический код, оно все еще очень быстро. Вы должны написать код самым простым способом - даже если это использует отражение - и только вернитесь, чтобы оптимизировать, если вы заметили проблемы с производительностью и изолировали их от использования рефлексии. В большинстве случаев у вас не будет никаких проблем. Отражение используется во всех видах высокочувствительного кода, например ASP.NET MVC.
Ответ 5
Вы можете использовать облегченную генерацию кода. Вот несколько статей:
Ответ 6
Отражение получило плохую репутацию от Java, где она (или, по крайней мере, используется) была очень медленной. Это не относится к .net, поэтому я не понимаю вашего возражения по его использованию. Также я согласен с Rex, вы не можете сказать, что что-то имеет низкую производительность без фактического измерения.