[转帖]C#重蹈覆辙?反射及元数据性能问题

本文深入探讨了C#中反射的性能问题,指出反射的绑定与调用不仅效率低下,而且由于元数据的存在,即便不使用反射也会带来显著的性能损耗。文中列举了WPF、Silverlight、ASP.NET MVC等.NET框架对反射的大量使用,强调了即便代码中未使用反射,元数据仍会占据程序大部分空间,从而影响运行效率。作者还批评了一些常见的错误性能评估方法,如函数计时论,认为全面的性能评估应考虑整体软件性能而非单一代码段。文章呼吁.NET社区关注反射和元数据对性能的影响,以优化软件性能。
摘要由CSDN通过智能技术生成

 

 

来源:FireLong-编程呓语博客 作者:FireLong-编程呓语博客 编辑:胡铭娅 

          【IT168评论】 在开始谈论性能问题之前,有必要首先理清几个基本点。我们谈C#,就是在谈.NET Framework(或者更准确一点是CLR,因 为.NET Framework除了CLR还包括BCL);谈.NET Framework(CLR),也就是在谈C#。因为支撑C#语法之后的就是整个 CLR的机制。因此,我说C#性能不好,和说CLR性能不好,说的是一个事情(就像说Java性能不好,就是说JVM性能不好一样)。我不希望在我下面说 C#某个地方性能不好的时候,再有论者立即指出来“那不是C#的问题,那是CLR的问题,或者.NET Framework的问题”——如果对C# 和.NET还停留在这个认识上,请先去读读Jeffrey Richter的《CLR via C#》一书,再来看我下面的文章。 

   另外,我说C#性能有问题,仅针对C#而言,与我对其他语言的态度无关。我既不是Java的支持者(因为Java的性能比C#还慢),也不是C++的支持 者(C++太过臃肿复杂),也不是C的支持者(没有基本的面向对象抽象和垃圾回收)。我既不喜欢任何语言,也不讨厌任何语言。编程语言在我只是一个工具 ——我只是希望这个工具是把锋利的牛刀,而不是把功能齐全的瑞士小刀。

  最后我不是毫无选择地反对“新功能”,我反对的是“添加的功能、没有重大抽象意义,却带来性能损失”,如果有“提高性能的新功能”——比如并发编程,或者“对管理软件复杂度”有重大意义,同时性能损失很小很小——比如面向对象,那我举双手赞成。”

  在理清了前面几个基本点之后,下面开始来针对我前文说过的一些问题一一“讲原理”。这篇文章中,我首先来剖析反射的性能问题。

  反射的两大类性能问题

  【一】反射绑定与调用——使用反射带来的性能问题

   反射的绑定与调用性能差,我想大概做过.NET开发的人都不会怀疑这一点。但是我还是希望那些严肃的程序员认真看看微软CLR程序经理 Joel Pobar在MSDN上的这篇文 章:Dodge Common Performance Pitfalls to Craft Speedy Applications  http://msdn.microsoft.com/en-us/magazine/cc163759.aspx,清楚理解反射绑定与调用的效率到底为 什么那么差?有多差?差在哪里?

  限于篇幅关系,我简单在这里总结一下,反射绑定与调用的性能问题(具体原理,大家参照MSDN这篇文章):

  首先要经过一个绑定过程,非常耗时(用字符串名称和metadata里面的字符串进行比对,字符串查找的算法大家都知道是很慢的操作)

  然后要进行参数个数、类型等的校验;如果不匹配还要搜索可能的类型转换

  进行CAS代码访问安全的验证,看允不允许调用。

  以上几个工作,如果不用反射应该是由C#编译器负责在编译时检查的。但是现在如果用反射,全都放到了运行时检查。

  这其中会产生一大堆的临时对象(比如MemberInfo Cache),给垃圾收集器造成巨大负担

  纵然有一些对反射绑定和调用的cache优化策略,Joel Pobar在这篇文章中给的最大的建议还是:能不用反射,则不用反射,因为性能成本太高。

  结论:反射调用的性能成本很高(参见msdn文章中中图2 Relative Performance of Invocation Mechanism)。

   我想这些性能问题,大家都会认可。但有些朋友会说“我.NET程序中用反射的很少啊?”,首先且不论你用的少不少,但是微软开发的很多 Application Framework对反射的使用现在越来越多,比如大量使用反射“绑定与调用”的例子(注意是大量,不是一点点!):

  WPF和Silverlight中的XAML序列化-反序列化,依赖属性,数据绑定

  ASP.NET MVC中路由、控制器,视图等的匹配查找(反射绑定)和调用(反射调用)

  WCF分布式通信中大量的实例激活,方法调用ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值