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

210

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

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

Дэн Герберт
источник
Вы также можете проверить этот вопрос. stackoverflow.com/questions/224232/…
smaclell
1
Используйте API на сайте fastflect.codeplex.com. Это увеличит скорость отражения в 500 раз для геттеров / сеттеров / инициаторов и некоторых других вещей. Источник и информация о том, как это работает, также есть, если вам нужно его расширить.
Брэндон Мур
3
Как эта информация проверяется в 2014 году? Что-нибудь изменилось за эти 4 года?
Arnthor
1
Простая задача присвоения значения свойству экземпляра примерно в 150 раз медленнее, если выполнять его с помощью отражения (PropertyInfo.SetValue (экземпляр, значение)), чем при простом кодировании (instance.property = value). Это в .NET 4.0
Thanasis Ioannidis

Ответы:

130

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

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

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

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

Мартин Маркончини
источник
Я использовал отражение, чтобы получить метод, имя класса текущего метода, чтобы записать ошибку в try-catch. в основном, чтобы избежать жесткого кодирования имени функции при регистрации ошибок. Мне нужно беспокоиться?
Санграм Нандхиле
@Sangram Нет, это хорошо
Karthik AMR
@Sangram нет, если только у вас не много ошибок, требующих постоянного отлова, что должно быть другой проблемой :)
Мартин Маркончини,
5
@Sangram, в то время как производительность отражения не должна быть проблемой в вашем случае, похоже, вы пытаетесь заново реализовать то, что предоставляют простые старые исключения, гораздо более элегантным способом
Яцек Горгонь»,
152

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

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

ESRogs
источник
18
Я тоже посещал Devscovery и согласен с этими результатами для .NET 3.5. Перекомпиляция программы тестирования производительности Devscovery для .NET 4 показывает значительное улучшение! Стоимость падает до 100 раз медленнее. Использование отражений для поиска typeof () не меняется между .NET 3.5 и .NET 4.
Джон Виггер,
61

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

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

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

График времени (y) в зависимости от количества населенных пунктов (x)

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

граната
источник
9
Не обязательно. Ваши DAL-конверсии могут быть только для нескольких тысяч элементов, но умножьте это на число одновременных пользователей, использующих ваше приложение (если оно веб-), и оно может сложиться так же, как если бы вы конвертировали миллион элементов. Если конкретный метод медленнее в 100 раз, он будет намного медленнее на маленьких и больших сетах. Медленнее медленнее.
Роберт Коритник
@RobertKoritnik Предполагается, что веб-методы на вашем сервере не являются асинхронными
Куррен
@kurren asynchronicity не влияет на отражение, а скорее на ресурсы сервера. Конечно, асинхронные веб-методы смогут обслуживать больше пользователей, но их отражение будет медленным. И отражение само по себе AFAIK в любом случае является синхронным процессом. С другой стороны, выборка данных будет единственной частью, которая будет хорошо играть в асинхронном дизайне.
Роберт Коритник
3
Что такое гипер-метод на графике? Чем он отличается от рефлектора?
Брайан Легенд
Я должен был сослаться на этот @LoneCoder: codeproject.com/Articles/18450/… by stackoverflow.com/users/23354/marc-gravell
граната
14

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

Дэвид Племптон
источник
12

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

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

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

Gaz
источник
Учитывая, что Visual Studio имеет такую ​​превосходную поддержку шаблонов, это практичный способ использовать генерацию кода
Себастьян
12

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

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

Quibblesome
источник
5
+1 за то, что научил меня новому слову: анафема. Также упоминание о иррациональных страхах. Я боюсь программистов, которые боятся иррационально - это показывает, что они действительно не знают, что делают, и просто основывают то, что они делают, на том, что им говорят другие люди. кашель груз культ кашель
bsneeze
1
Ахххх Грузовой Культ. Теперь есть прекрасный пример любопытного человеческого поведения.
Ужасно
10

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

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

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

McKenzieG1
источник
13
чтобы быть справедливым, проверка типа отражения быстро.
Джимми
1
Для такого «критичного к производительности кода» следует ли вам действительно использовать .NET для начала?
Seph
1
@Seph: Динамические / отражающие части .NET, нет. Но обычный C # / .NET, почему бы и нет? Ускорения C ++ и C # незначительны на прикладном уровне (C ++ все еще на несколько% быстрее в интенсивных математических процедурах). И я предполагаю, что вы не предлагаете сборку ...
DeepSpace101
Тип значения в штучной упаковке (т.е. объект) может быть заблокирован. @ БрайсВагнер правильный.
Птица
1
Чтобы быть справедливым (для меня), точнее было бы сказать, что ответ "устарел", а не "полная чепуха". Мои замечания о поведении lock (obj) были точны в то время, когда они были написаны, но это специфическое для реализации поведение CLR давно прошло.
McKenzieG1
5

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

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

Майк Томпсон
источник
3

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

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

Ака
источник
3

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

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

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

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

депутатах.
источник
3

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

Это довольно распространенный сценарий, и на MSDN есть статья « Использование отражения для привязки бизнес-объектов к элементам управления ASP.NET». которой рассматриваются проблемы производительности.

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

lomaxx
источник
2

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

Крис Питчманн
источник
1

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

tsimon
источник