Почему отражение не работает хорошо в.NET?

double dSqrd = Math.Pow(d,2.0); 

более точно, чем

double dSqrd = d * d; // Here we can lose precision
5
задан Shog9 22 July 2009 в 01:34
поделиться

7 ответов

Отражение работает хорошо, просто оно делает намного больше, чем статический код.

Допустим, у вас есть этот фрагмент кода:

typeof(SomeClass).GetMethod("SomeStaticMethod").
Invoke(null, new object[] { 1, 2, 3 });

Это то же самое:

SomeClass.SomeStaticMethod(1, 2, 3);

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

И это, вероятно, очень общее резюме, несомненно, происходит даже больше. Тем не менее, несмотря на это, отражение по-прежнему очень быстрое и используется во многих областях, от привязки данных в WinForms до привязки модели в ASP.NET MVC (каждый запрос, который вы делаете на этот сайт, построенный на MVC, включает в себя целую кучу отражений, но все же ,

2
ответ дан 18 December 2019 в 05:49
поделиться

отражение не работает хорошо

Это очень загруженный оператор. «Хорошие результаты» относительны. По сравнению со статическим кодом, рефлексивные вызовы выполняют не так хорошо . Однако почти во всех случаях отражение в .NET выполняется чрезвычайно быстро . Я не могу этого преуменьшить. Отражение получило плохую репутацию со времен .NET 1.x и, возможно, других языков, но отражение в .NET 2.0+ невероятно быстрое .

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

16
ответ дан 18 December 2019 в 05:49
поделиться

Простое заявление о том, что «Reflection» работает медленно, - значит, скрыть чертовски много функций под очень широким слоем. Отражение в .NET состоит из нескольких классов, каждый с разным уровнем «производительности». Во-первых, использование оператора typeof () на самом деле является формой отражения ... он запрашивает тип в метаданных CLR. Однако, typeof () выполняется чрезвычайно быстро (почти за свободное время). Использование других связанных с типами "отражений", таких как оператор is, оператор sizeof () и т. Д., также почти бесплатны (они в основном работают, как если бы они были статическим кодом).

Отражение, используемое для получения информации о типе, хотя и медленнее, чем typeof () , также очень и очень быстрое, учитывая количество обход указателя и продолжающееся зондирование метаданных. Проверка метаданных - довольно распространенная практика с кодом .NET, особенно когда дело доходит до работы с настраиваемыми атрибутами.

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

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

Приложение:

Немного после размышлений, но если вам требуется высокая степень динамического вызова позднего вызова. связанных членов типа, вам следует изучить облегченную генерацию кода. Используя пространство имен System.Reflection.Emit, вы можете использовать такие утилиты, как DynamicMethod, для генерации облегченного кода во время выполнения, который может выполнять вызовы с ранней привязкой. Кэширование этого сгенерированного кода снижает начальные затраты на его создание, позволяя получить преимущества вызовов с поздним связыванием с производительностью раннего связывания.

5
ответ дан 18 December 2019 в 05:49
поделиться

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

Случаи с опозданием MethodBase.Invoke, DynamicMethod через Invoke, Type.InvokeMember и вызовы делегатов с поздним связыванием (вызывает делегаты через Delegate.DynamicInvoke). Все эти методы включают значительно более отрицательный последствия для производительности, чем ранние дела. Даже в лучшем случае они обычно порядка величина медленнее самого медленного случай раннего связывания.

Он нарушает наши довольно много тестов производительности различных способов выполнения вызовов с ранним и поздним связыванием. Стоит прочитать.

4
ответ дан 18 December 2019 в 05:49
поделиться

Потому что он включает поиск строк (типов и имен членов) во время выполнения, а также дополнительную упаковку / распаковку для типов значений.

1
ответ дан 18 December 2019 в 05:49
поделиться

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

Этот процесс дорог по 2 причинам. 1- Идет много поисков. 2- Касание страниц, которые обычно не затрагиваются (холодные страницы), которые содержат таблицы метаданных.

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

1
ответ дан 18 December 2019 в 05:49
поделиться

Отражение хорошо работает в .NET - для того, что оно делает.

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

Это не значит, что это действительно медленно - это просто НАМНОГО медленнее, чем полностью скомпилированный , вызовы и поиск прямых методов. Так и должно быть, но я думаю об этом больше, потому что скомпилированный код в любой системе быстрее, чем динамический поиск информации.

0
ответ дан 18 December 2019 в 05:49
поделиться
Другие вопросы по тегам:

Похожие вопросы: