Ответ 1
Когда вы думаете об этом, размышления довольно впечатляют, насколько быстро это происходит.
Кэшированный делегат из ConstructorInfo
или MethodInfo
может быть вызван со скоростью, сравнимой с любым другим делегатом.
Делегат, созданный из ILGenerator.Emit
(который, кстати, не является новым, он был в .NET с версии 1), можно также вызвать так же быстро.
Объект, полученный путем выдачи или вызова делегата ConstructorInfo
, будет таким же быстрым, как и любой другой объект.
Если вы получаете объект, загружая сборку динамически, используя отражение, чтобы найти метод для вызова и вызова его, и он реализует определенный интерфейс, через который вы вызываете его с этого момента, тогда он будет таким же быстро в том, как он используется в качестве другой реализации этого интерфейса.
В целом, рефлексия дает нам способы делать то, что без него мы бы - если бы мы могли сделать их вообще - должны использовать методы, которые медленнее как для кодирования, так и для выполнения.
Это также дает нам возможность делать вещи более сложные, более хрупкие, менее безопасные по типу и менее эффективные, чем другие средства. Практически каждая строка кода С# может быть заменена большим фрагментом кода, который использует отражение. Этот код почти наверняка будет хуже, чем исходная строка целым рядом способов, а производительность - наименьшая из них.
Вполне возможно, что "избегать размышлений, потому что его медленный" совет проистекает из убеждения, что тот разработчик, который сойдет с ума по какой-либо новой технике, просто потому, что он казался классным, был бы тем видом, который, скорее всего, был бы предупрежден "им" "будет медленнее", чем "он будет менее идиоматичным, более подверженным ошибкам и сложнее поддерживать". Вполне возможно, что это убеждение совершенно правильно.
В большинстве случаев, когда наиболее естественным и очевидным подходом является использование рефлексии, тогда он также будет не менее результативным, чем действительно запутанная попытка избежать этого.
Если проблемы с производительностью относятся к чему-либо в отражении, это действительно относится к скрытым:
Использование dynamic
может показаться разумным в случае, когда только небольшая работа может его избежать. Здесь можно счесть разницу в производительности.
В ASP.NET использование <%#DataBinder.Eval(Container.DataItem, "SomeProperty")%>
проще, но обычно менее результативно, чем <#((SomeType)Container.DataItem).SomeProperty%>
или <%#SomeCodeBehindProvidedCallWithTheSameResult%>
. Я по-прежнему буду использовать прежние 90% времени, а последний, только если я действительно забочусь о производительности данной страницы или, что более вероятно, потому что выполнение многих операций над одним и тем же объектом делает последнее более естественным.
Таким образом, во всех, все остается "медленным" на компьютерах, в то время как они ограничены требованием работать в одной вселенной таким образом, что потребляет энергию и требует времени, для некоторой ценности "медленного". Различные методы отражения имеют разные затраты, но также и альтернативы. Остерегайтесь не столько отражения в тех случаях, когда это очевидный подход, как скрытое отражение, когда другой подход немного менее очевидный может служить хорошо.
И, конечно, код мудро с любой техникой, которую вы используете. Если вы собираетесь называть один и тот же делегат сто раз подряд, вы должны хранить его, а не получать его каждый вызов, и это будет идти, путь к его получению был через отражение или нет.