Вопрос

Мне сказали использовать Reflection.Emit вместо PropertyInfo.GetValue / SetValue, потому что так быстрее. Но я действительно не знаю, что из Reflection.Emit и как его использовать для замены GetValue и SetValue. Кто-нибудь может мне помочь с этим?

Это было полезно?

Решение

Просто альтернативный ответ; если вам нужна производительность, но похожий API - рассмотрите HyperDescriptor ; он использует Reflection.Emit снизу (так что вам не нужно), но выставляет себя в API PropertyDescriptor , так что вы можете просто использовать:

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
props["Name"].SetValue(obj, "Fred");
DateTime dob = (DateTime)props["DateOfBirth"].GetValue(obj);

Одна строка кода, чтобы включить его, и он обрабатывает все кэширование и т. д.

Другие советы

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

Я использовал это в своей реализации буферов протокола, и это имело огромное значение по сравнению с PropertyInfo.GetValue / SetValue . Как уже говорили другие, делайте это только после того, как докажете, что самый простой способ слишком медленный.

У меня есть сообщение в блоге с более подробной информацией, если вы решите пойти по маршруту CreateDelegate .

Использовать PropertyInfo.GetValue / SetValue

Если у вас есть проблемы с производительностью, кэшируйте объект PropertyInfo (не вызывайте GetProperty повторно)

Если - и только если - использование отражения является узким местом производительности вашего приложения (как видно в профилировщике), используйте Delegate.CreateDelegate

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

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

И если доступ к свойствам во время выполнения - это ваше узкое место в производительности, то, вероятно, лучше использовать доступ во время компиляции (трудно одновременно быть и универсальной, и сверхвысокой производительностью).

Назначение Reflection.Emit полностью отличается от PropertyInfo.Get / SetValue. С помощью Reflection.Emit вы можете напрямую генерировать код IL, например, в динамически скомпилированные сборки и выполнять этот код. Конечно, этот код может получить доступ к вашим свойствам.

Я серьезно сомневаюсь, что это будет намного быстрее, чем в конце концов использовать PropertyInfo, и для этого он тоже не предназначен. Например, вы можете использовать Reflection.Emit в качестве генератора кода для небольшого компилятора.

Использование Reflection.Emit кажется слишком "умным", а также преждевременной оптимизацией. Если вы профилируете свое приложение и обнаружите, что отражение GetValue / SetValue является узким местом, тогда вы можете подумать об оптимизации, но, вероятно, даже тогда ...

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top