反思真的很慢吗?

Bha*_*kar 10 c# reflection performance

这是一种普遍的看法,即反思很慢,并试图尽可能地避免它.但在目前的情况下,这种信念是否属实?当前的.net版本有很多变化,比如使用IL Weaving(即IL Emit)等,而不是传统的PropertyInfo和MethodInfo执行反射的方式.

这是否有任何令人信服的证据,新的反映不再那么慢,而且可以使用.是否有更好的方法来读取属性数据?

谢谢,巴斯卡

Jon*_*nna 12

当你想到它时,反射速度对它的速度有多么令人印象深刻.

来自ConstructorInfoMethodInfo可以调用高速缓存的委托,其速度可与任何其他委托相媲美.

ILGenerator.Emit(顺便说一下,不是新的,从版本1开始就在.NET中)创建的委托也可以同样快速地调用.

通过发出或调用代理获得的对象ConstructorInfo将与任何其他对象一样快.

如果您通过动态加载程序集来获取对象,使用反射来查找要调用的方法并调用它,并且它实现了一个已定义的接口,您可以通过该接口从该点开始调用它,那么它将如何快速地它被用作该接口的另一个实现.

总而言之,反射为我们提供了做事的方法,没有它我们会 - 如果我们可以完成它们 - 必须使用速度慢的代码和执行技术.

它还为我们提供了比其他方法更复杂,更脆弱,更少类型安全且性能更低的方法.几乎每一行C#代码都可以被一大堆使用反射的代码所取代.在很多方面,这段代码几乎肯定会比原始代码更糟糕,而性能是其中最少的.

很可能"避免反思,因为它的缓慢"建议源于这样一种信念,即那种因为看似很酷而会为任何新技术而疯狂的开发者将更有可能被"它将被警告"所警告.慢"而不是"它会更少惯用,更容易出错并且难以维持".很可能这种信念是完全正确的.

然而,在大多数情况下,当最自然和最明显的方法是使用反射时,它的性能也不会低于真正错综复杂的避免它的尝试.

如果性能问题适用于反射中的任何内容,那么它实际上是隐藏的用途:

dynamic在只有少量工作可以避免它的情况下,使用似乎是明智的.这里的性能差异可能值得考虑.

在ASP.NET中,使用<%#DataBinder.Eval(Container.DataItem, "SomeProperty")%>更容易,但通常性能低于<#((SomeType)Container.DataItem).SomeProperty%><%#SomeCodeBehindProvidedCallWithTheSameResult%>.我仍然会使用前者的90%,而后者只有在我真正关心给定页面的性能时才会使用,或者更可能因为对同一个对象进行多次操作会使后者更自然.

总而言之,计算机中的一切仍然"缓慢",而它们受限于需要以一种消耗能量并花费时间的方式在单个宇宙中工作,一些"慢"的价值.不同的反射技术有不同的成本,但替代方案也是如此.在那些显而易见的隐藏反射方法的情况下,请注意不要那么多的反思,而另一种稍微不那么明显的方法可能会很好.

当然,使用您使用的任何技术明智地编码.如果你要连续一百次调用同一个委托,那么你应该存储它而不是每次调用都能获得它,那么获取它的方式是否通过反射来实现.


Chr*_*cht 7

这完全取决于.
是的,使用反射毫无疑问比不使用反射慢,但你必须看一下大局:

例如,假设您的代码进行了一些反射,然后通过网络从数据库加载一些数据.
在这种情况下,您可以完全忽略反射的额外成本,因为通过网络的数据库请求可能需要更长时间.