Насколько дорого стоит .NET отражение? - PullRequest
201 голосов
/ 25 августа 2008

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

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

Ответы [ 13 ]

147 голосов
/ 27 августа 2008

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

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

125 голосов
/ 25 августа 2008

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

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

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

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

57 голосов
/ 14 декабря 2010

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

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

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

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

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

14 голосов
/ 02 мая 2009

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

12 голосов
/ 01 сентября 2008

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

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

12 голосов
/ 31 августа 2008

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

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

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

10 голосов
/ 31 августа 2008

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

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

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

5 голосов
/ 25 августа 2008

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

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

3 голосов
/ 25 мая 2009

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

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

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

Обыщите источник и посмотрите, что делается.

3 голосов
/ 25 августа 2008

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

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

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