Сведения о вопросе

Drake

08:33, 21st August, 2020

Теги

c#   .net   performance   reflection    

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

Просмотров: 441   Ответов: 13

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

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



  Сведения об ответе

DINO

00:20, 19th August, 2020

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

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


  Сведения об ответе

DINO

20:14, 7th August, 2020

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

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

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

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


  Сведения об ответе

ASSembler

07:37, 14th August, 2020

Производительность отражения будет зависеть от реализации (повторяющиеся вызовы должны быть кэшированы, например: 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 циклов. Большинство DALs возвращает только несколько сотен или, возможно, тысяч строк одновременно, и на этих уровнях отражение работает просто отлично.


  Сведения об ответе

PROGA

04:09, 11th August, 2020

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


  Сведения об ответе

+-*/

11:23, 21st August, 2020

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

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


  Сведения об ответе

lourence

17:46, 14th August, 2020

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

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

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


  Сведения об ответе

lourence

21:06, 1st October, 2020

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

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

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


  Сведения об ответе

DO__IT

23:07, 5th August, 2020

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

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


  Сведения об ответе

ITSME

12:16, 8th August, 2020

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

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

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


  Сведения об ответе

lats

05:22, 25th August, 2020

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

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


  Сведения об ответе

JUST___

18:53, 27th August, 2020

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

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

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

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


  Сведения об ответе

P_S_S

10:23, 3rd August, 2020

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


  Сведения об ответе

$DOLLAR

06:30, 28th August, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться