Насколько дорого стоит .NET-отражение?

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

Для тех, кто использовал отражение в приложениях, вы измеряли показатели производительности и, действительно ли это так плохо?

Ответ 1

Это. Но это зависит от того, что вы пытаетесь сделать.

Я использую отражение для динамической загрузки сборок (плагинов), а его производительность "штраф" не является проблемой, так как операция - это то, что я делаю во время запуска приложения.

Однако, если вы отражаетесь внутри серии вложенных циклов с призывами отражения к каждому, я бы сказал, что вы должны пересмотреть свой код:)

Для операций "несколько раз" отражение вполне приемлемо, и вы не заметите никаких задержек или проблем с ним. Это очень мощный механизм, и он даже используется .NET, поэтому я не понимаю, почему вы не должны его попробовать.

Ответ 2

В своем выступлении "Эффективность повседневных вещей" , Джефф Рихтер показывает, что вызов метода путем отражения примерно в 1000 раз медленнее, чем называть его нормально.

Совет Джеффа: если вам нужно вызвать метод несколько раз, используйте однократное отражение, чтобы найти его, затем назначьте его делегату, а затем вызовите делегата.

Ответ 3

Эффективность отражения будет зависеть от реализации (повторяющиеся вызовы должны быть кэшированы, например: entity.GetType().GetProperty("PropName")). Поскольку большая часть отражения, которое я вижу на повседневной основе, используется для заполнения объектов из устройств чтения данных или других структур типа репозитория, я решил сравнить производительность, особенно с отражением, когда она используется для получения или установки свойств объектов.

Я разработал тест, который, на мой взгляд, справедлив, так как он кэширует все повторяющиеся вызовы и только раз вызывает вызов SetValue или GetValue. Весь исходный код теста производительности находится в битбакете: https://bitbucket.org/grenade/accessortest. Scrutiny приветствуется и поощряется.

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

Graph of time (y) against number of entities populated(x)

На приведенном выше графике показан результат моего небольшого теста и показано, что механизмы, которые превосходят отражение, делают это заметно только после отметки 100 000 циклов. Большинство DAL только возвращают несколько сотен или, может быть, тысячи строк за раз, и на этих уровнях отражение выполняется просто отлично.

Ответ 4

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

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

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

Ответ 5

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

В Compact Framework (в котором я обычно участвую), это довольно много anethema, и в большинстве случаев его следует избегать, как чуму, Я все еще могу избавиться от использования этого нечасто, но я должен быть очень осторожным с его применением, что гораздо менее забавно.: (

Ответ 6

Если вы не в цикле, не беспокойтесь об этом.

Ответ 7

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

Следующий пример устарел - true в то время (2008), но давно исправлен в более поздних версиях CLR. Отражение в целом все еще несколько дорогостоящее, хотя!

Пример: вы никогда не должны использовать элемент, объявленный как "Объект" в инструкции блокировки (С#)/SyncLock (VB.NET) в высокопроизводительном коде. Зачем? Поскольку CLR не может блокировать тип значения, что означает, что он должен выполнить проверку типа отражения во время выполнения, чтобы узнать, действительно ли ваш объект является типом значения вместо ссылочного типа.

Ответ 8

Как и во всех вещах в программировании, вы должны балансировать стоимость работы с любой полученной выгодой. Отражение - неоценимый инструмент при использовании с осторожностью. Я создал библиотеку отображения O/R в С#, которая использовала отражение для привязки. Это работало фантастически хорошо. Большая часть кода отражения выполнялась только один раз, поэтому любой удар производительности был довольно небольшим, но преимущества были большими. Если бы я писал новый алгоритм сортировки по fandangled, я бы, вероятно, не использовал бы отражение, так как он, вероятно, будет плохо масштабироваться.

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

Ответ 9

Как и все, все об оценке ситуации. В DotNetNuke существует довольно основной компонент с именем FillObject, который использует отражение для заполнения объектов из datarows.

Это довольно распространенный сценарий, и есть статья о MSDN, Использование Reflection to Bind Business Objects для элементов управления ASP.NET Form, которая охватывает проблемы с производительностью.

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

Ответ 10

Отражение может оказать заметное влияние на производительность, если вы используете его для создания частых объектов. Я разработал приложение, основанное на Composite UI Application Block, который опирается на отражение в значительной степени. Наблюдалось заметное ухудшение производительности, связанное с созданием объектов посредством отражения.

Однако в большинстве случаев нет проблем с использованием рефлексии. Если вам нужна только проверка сборки, я бы рекомендовал Mono.Cecil, который очень легкий и быстрый

Ответ 11

Отражение является дорогостоящим из-за многих проверок, которые должно выполняться во время выполнения, когда вы делаете запрос для метода, который соответствует списку параметров. Где-то глубоко внутри существует код, который перебирает все методы для типа, проверяет его видимость, проверяет тип возврата, а также проверяет тип каждого параметра. Весь этот материал стоит времени.

Когда вы выполняете этот метод внутри, вы получаете некоторый код, который делает что-то вроде проверки того, что вы передали совместимый список параметров перед выполнением фактического целевого метода.

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

Протыкайтесь вокруг источника и посмотрите, что делается.

Ответ 12

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

Ответ 13

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