我有兴趣知道技术原因:为什么反射在.NET中表现不好?为什么在.NET中反射效果不好?
回答
反射性能很好,它只是确实比静态代码多。
说你有这样的代码片段:
typeof(SomeClass).GetMethod("SomeStaticMethod").
Invoke(null, new object[] { 1, 2, 3 });
这是与此相同:
SomeClass.SomeStaticMethod(1, 2, 3);
但它应该是显而易见的是,第一个有很多工作要做。它必须获取类型信息,遍历它以查看是否存在SomeStaticMethod方法,检查它是什么类型的方法,在实例上调用该方法,或者如果它是静态的,则不传递对象数组参数,装箱/拆箱整数在这种情况下也是如此。
这可能是一个非常广泛的总结,毫无疑问更多的事情正在进行。尽管如此,反射速度仍然很快,并在很多领域使用,从WinForms的数据绑定到ASP中的模型绑定。NET MVC(你对这个站点建立的每一个请求,建立在MVC上,涉及到大量的反射,然而,这个站点非常快,MVC被认为是一个非常快速的框架)。
因为它涉及在运行时查找的字符串(类型和成员名称的),以及额外的装箱/拆箱值类型。
上了不起的文章MSDN:Dodge Common Performance Pitfalls to Craft Speedy Applications。基本上,这是一个迟到和早期约束的问题。也就是说,可以在编译时决定什么,以及在运行时必须决定什么。那篇文章...
后期绑定案件 MethodBase.Invoke,DynamicMethod的通过 调用,Type.InvokeMember和 后期绑定代理呼叫(通过Delegate.DynamicInvoke上 代表呼叫)。 所有这些方法都具有比 早期绑定的情况下 显著负 性能的影响。即使在最好的情况下,它们的典型范围是 的幅度比最慢的 早期的情况。
他打破了我们进行早期和晚期调用的各种方式的不少性能测试。值得一读。
反射涉及将元数据来解析名称的标记,它然后使用该令牌进行查找和检索所需的数据(例如,一个方法令牌用于获取有关方法的信息,参数.. 。等等)。
由于2个原因,此过程很昂贵。 1-很多查找正在进行中。 2-触摸通常不会触及的页面(冷页面),其中包含元数据表格。
直接访问元数据非常昂贵,CLR维护缓存以使此过程更快,并避免在以非反射方式访问事物时触及元数据表,但是一旦进入反射状态,我们会绕过这些缓存并直接进入来源。
反射效果并不是很好
这是一个非常加载声明。 “表现良好”是相对的。与静态代码相比,反射式呼叫不会执行,也不会执行。但是,在几乎所有情况下,.NET中的反射都是非常快的。我无法低估这一点。反思在.NET 1.x和其他语言中得到了不好的声誉,但是在.NET 2.0+中的反射是,并且很快就出现了。
的情况下,99%的“是反映太慢”是一个无关紧要的问题。我怀疑你需要费心衡量一个反射电话对静态电话的性能影响。
反射在.NET中表现良好 - 它具有的功能。
然而,反思,因为它已经编译类型的运行时分析,需要相当多的开销。一般来说,像静态类型信息的字符串查询,以及漫游类元数据等,都需要一段时间。
这并不是说它真的很慢 - 它只是比完全编译的海峡方法调用和查找慢得多。它应该是 - 但我真的更多地想到它,因为在任何系统中,编译代码比动态查找信息更快。
简单地说,“反射”执行缓慢是在很宽的毯子底下包含许多功能的地狱。 .NET中的反射有几个类,每个类都有不同的“性能”级别。首先,使用typeof()
运算符实际上是一种反射形式...它查询CLR元数据的类型。然而,typeof()
执行得非常快(在接近空闲时间)。使用其他类型相关的“反射”,如is运算符,sizeof()
运算符等也几乎是免费的(它们基本上就像静态代码一样执行。 )
考虑到指针遍历和元数据探测的数量,用于检索类型信息的反射速度比typeof()
慢,也是非常非常快的。元数据探测是.NET代码的一种常见做法,尤其是在处理自定义属性时。
关于反射的重要性能问题与调用有关。访问类型信息和读取元数据的权重相当轻。当涉及动态调用属性,索引器,方法或通过反射动态构造新类型时,您会获得数量级的性能优势。
反射仍然是一个进程内执行,所以在你担心动态调用的性能下降之前,请确保没有任何明显更大的性能瓶颈,如进程间执行,网络调用(即数据库,Web服务等)当涉及到性能时,从最大的性能开始,然后从这里开始。包括动态调用在内的反射通常是从性能角度考虑的最后一件事情。
附录:
的思想后一点,但如果你需要高度的后期绑定类型成员的动态调用的,你应该看看轻量级代码生成。使用System.Reflection.Emit命名空间,您可以使用DynamicMethod等实用程序在运行时生成轻量级代码,以执行早期绑定的调用。对生成的代码进行缓存可以降低生成代码的初始成本,使您可以利用早期绑定的性能获得后期绑定的呼叫。
- 1. 正在使用.Net中的反射效果相当不好?
- 2. 为什么在.NET中投射速度比反射速度快?
- 3. 反射有什么好处?
- 4. 什么是.NET反射的“成本”?
- 5. 反射不适用于CCScene,为什么?
- 6. 为什么推荐使用.NET中的反射?
- 7. Android:反射不好?
- 8. Silverlight的:反射效果
- 9. java泛型和反射,为什么不同的结果
- 10. 为什么无效异步不好?
- 11. DotNet反射器 - 为什么我不能反汇编XmlHierarchicalEnumerable?
- 12. 为什么不填充任何效果
- 13. .Net反射GetProperties()
- 14. 为什么反射速度很慢?
- 15. Scala反射 - 为什么TypeTag和Type?
- 16. VB .Net - 反射:在调用方法之前,从加载的程序集反射的方法执行。为什么?
- 17. 的GetType在.NET反射不起作用
- 18. 隐藏iCarousel项目反射效果
- 19. .NET中的深度反射
- 20. 单反的.NET反射器
- 21. 为什么不在jQuery中使用这种弹跳效果?
- 22. 镜像效果,为什么需要做按位反转?
- 23. ol3 drag overlay在chrome中效果不好
- 24. jQuery in wordpress在ie8中效果不好
- 25. Java反射API中反射的方法是什么?
- 26. .NET通过反射
- 27. modopt和.NET反射
- 28. 为什么Assembly.GetType()在加载不同装配时反映了反射装配?
- 29. 什么是反射,它可以在c#中使用什么?
- 30. 为什么数据为中心不好?
嗯,我在Windows窗体应用程序中使用反射来创建一个动态的用户界面,我没有看到任何性能问题。当然,在我不知道的“高性能关键”应用程序中可能会有所不同。 – Malcolm 2009-07-22 01:43:50