Отражение: использование отражения все еще «плохое» или «медленное»? Что изменилось с отражением с 2002 года?

21

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

И что, если что-то изменилось? Это просто скорость машин? Были ли изменения в структуре, чтобы ускорить рефлексию?

Или ничего не изменилось? Это все еще "плохо" или "медленно" использовать отражение?

blesh
источник
2
Отражение всегда будет медленнее, чем прямые звонки, потому что вам нужно выполнить несколько шагов, чтобы найти и проверить, существует ли то, что вы звоните.
Майкл К
Это всегда было плохо .... Конечно, иногда у вас нет выбора, это зависит от программиста, чтобы знать, когда это время, и избегать этого в противном случае.
Ramhound
Выполнение отражения с помощью gettype для извлечения одного элемента из перечисления все еще более чем в 30 раз быстрее, чем создание исключения с помощью Enum.Parse (). Так что отражение иногда побеждает.
Brain2000

Ответы:

16

Отражение не является ни плохим, ни медленным. Это просто инструмент. Как и все инструменты, это очень ценно для определенных сценариев, но не так ценно для других.

Если производительность действительно является проблемой, вы всегда можете использовать такую ​​библиотеку, как FasterFlect .

Дальнейшее чтение
Если рефлексия неэффективна, когда она наиболее уместна?

Роберт Харви
источник
Или dynamic- по-видимому, на порядок быстрее, чем отражение.
Одд
1
Производительность не проблема вообще. Я просто очень хорошо помню людей, избегавших размышлений в 2002 году, как будто это была чума. Мне интересно, что изменилось с тех пор.
блеф
3
@blesh: ничего. Люди теперь более знакомы с этим и меньше боятся этого.
Роберт Харви
5
Я мог бы все «сойти с газона» здесь и сказать, что Лисп имел это задолго до того, как ООП существовал ...
Майкл К
Справедливо. Мне было просто интересно, было ли это увеличение скорости в машинах за последние десять лет, которое имело значение, или были действительно внесены изменения в System.Reflection, которые повысили производительность.
блеф
17

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

Используя рефлексию, некоторые важные предположения, которые обычно можно сделать относительно исходного кода, нарушаются, и такие инструменты, как «Найти все ссылки», перестают работать надежно. Отражение также в основном устраняет большую часть безопасности типов, которую обеспечивает компилятор, скажем, в C #, и большинство ошибок программирования, которые система типов обычно перехватывает и переводит в ошибки компилятора, теперь в лучшем случае становятся ошибками времени выполнения или, в худшем случае, очень неясными ошибками.

Так почему же тогда люди используют отражение? Проще говоря, потому что, несмотря на проблемы, описанные выше, это очень ценный инструмент. С отражением, некоторые преимущества динамического программирования могут быть получены в статическом, строго типизированном языке, таком как C #, и языки динамического программирования недавно показали свои достоинства, особенно в области веб-программирования - PHP, Javascript и довольно заметный Python. Все они используют динамическую типизацию и хорошо подходят для веб-программирования. Но поскольку язык по-прежнему C #, вы можете оставить большую часть своего приложения в строго типизированном языке ООП и написать небольшую часть, в которой динамическое поведение действительно имеет значение для отражения.

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

tdammers
источник
13

Отражение все еще значительно медленнее, чем прямые звонки. Две вещи изменились:

  • Среда выполнения оптимизировала механизмы отражения, так что разница стала меньше
  • Процессоры стали быстрее, так что небольшие неэффективности легче переносить

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

Майкл Боргвардт
источник
4
увы, процессоры стали медленнее - обычно на мобильных устройствах, а также на сервере, где люди пытаются выжать из своих серверов как можно большую эффективность из-за затрат на их эксплуатацию.
gbjbaanb
@gbjbaanb: Я дам вам мобильные устройства, но на сервере покупка большего количества оборудования вместо оптимизации кода является приемлемым и рациональным выбором в подавляющем большинстве случаев, потому что затраты на покупку и эксплуатацию серверов намного ниже, чем затраты на оптимизацию кода.
Майкл Боргвардт
2
В некоторых ситуациях затраты на сервер значительно превышают затраты на разработку. В широком масштабе. Несмотря на то, что серверы работают нормально, производительность может быть даже более критичной, чем на клиентском компьютере. Это индивидуальный сценарий.
Лорд Тидус
1
@Lord Tydus: конечно, но случай, который вы описываете, является редким исключением.
Майкл Боргвардт