Насколько дорого обходится рефлексия .NET?

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

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

Вы также можете проверить этот вопрос. stackoverflow.com/questions/224232/…

smaclell 16.01.2009 06:46

Используйте api на сайте Fastflect.codeplex.com. Это ускорит отражение примерно в 500 раз для геттеров / сеттеров / инициаторов и некоторых других вещей. Источник и информация о том, как это работает, тоже есть, если вам нужно его расширить.

Brandon Moore 10.02.2012 11:25

Как эта информация проверяется в 2014 году? Что-нибудь изменилось за эти 4 года?

Arnthor 31.03.2014 15:23

Простая задача присвоения значения свойству экземпляра примерно в 150 раз медленнее, чем при отражении (PropertyInfo.SetValue (instance, value)), чем при простом кодировании (instance.property = value). Это в .NET 4.0.

Thanasis Ioannidis 22.01.2015 01:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
214
4
62 023
13
Перейти к ответу Данный вопрос помечен как решенный

Ответы 13

Ответ принят как подходящий

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

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

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

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

Я использовал отражение, чтобы получить метод, имя класса текущего метода для регистрации ошибки в try-catch. в основном, чтобы избежать жесткого кодирования имени функции при регистрации ошибки. Мне нужно волноваться?

Sangram Nandkhile 18.12.2015 09:32

@Sangram нет, это нормально

Karthik AMR 03.10.2016 14:37

@Sangram нет, если у вас не много ошибок, требующих постоянного отлова, что тогда должно быть другой проблемой :)

Martin Marconcini 03.10.2016 19:18

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

Jacek Gorgoń 28.12.2016 03:50

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

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

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

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

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

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

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

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

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

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

John Wigger 08.04.2011 03:33

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

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

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

честно говоря, проверка типа отражения выполняется быстро.

Jimmy 10.01.2009 01:16

Стоит ли вам действительно начинать с .NET для такого «кода, критичного к производительности»?

Seph 14.05.2012 15:56

@Seph: динамические / отражающие части .NET, нет. Но обычный C# /. NET, почему бы и нет? Ускорение C++ по сравнению с C# незначительно на уровне приложений (C++ по-прежнему на несколько% быстрее в интенсивных математических процедурах). И я предполагаю, что вы не предлагаете сборку ...

DeepSpace101 31.01.2013 21:36

Тип значения в штучной упаковке (например, объект) может быть заблокирован. @BryceWagner прав.

Fowl 08.11.2013 08:44

«CLR не может заблокировать тип значения» на самом деле означает, что если вы попытаетесь, например, lock(53), тогда int будет упакован, а созданный объект заблокирован, что будет отличаться от объекта, заблокированного другим вызовом, и, следовательно, на самом деле ничего не заблокирует. Выполнение private lockObj = 53, а затем lock(lockObj) будет работать отлично. Бит "проверка типа отражения во время выполнения" в этом ответе - просто чушь.

Jon Hanna 12.03.2014 19:14

Честно говоря (ко мне), правильнее сказать, что ответ «устаревший», а не «полная чушь». Мои замечания о поведении lock (obj) БЫЛИ точными в то время, когда они были написаны, но этого поведения CLR, зависящего от реализации, уже давно нет.

McKenzieG1 05.05.2014 20:36

Я категорически не согласен с этим ответом.

Vahid Amiri 20.06.2016 20:48

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

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

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

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

Sebastian 07.01.2014 19:04

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

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

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

bsneeze 02.05.2009 05:29

Ahhhh Cargo Cult. Теперь есть прекрасный пример любопытного человеческого поведения.

Quibblesome 02.05.2009 22:48

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

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

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

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

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

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

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

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

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

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

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

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

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

Robert Koritnik 26.07.2012 17:17

@RobertKoritnik Предполагается, что веб-методы на вашем сервере не являются асинхронными

Kurren 22.10.2014 19:10

@kurren asynchronicity влияет не на отражение, а на ресурсы сервера. Асинхронные веб-методы, конечно, смогут обслуживать большее количество пользователей, но рефлексия все равно будет медленной. И отражение само по себе AFAIK в любом случае является синхронным процессом. С другой стороны, выборка данных будет единственной частью, которая хорошо сочетается с асинхронным дизайном.

Robert Koritnik 22.10.2014 19:24

Что такое гипер-метод на графике? Чем он отличается от Reflector?

Bryan Legend 25.05.2015 22:27

Я должен был сослаться на этот @LoneCoder: codeproject.com/Articles/18450/… от stackoverflow.com/users/23354/marc-gravell

grenade 26.05.2015 16:16

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