利用表达式树构建委托改善反射性能 分类: .NET 2014-02-20 10:34 348人阅读 评论(0) 收藏
2014-02-20 10:34
393 查看
最近搞一个系统时由于在比较关键地方用到反射了,所以要关注了一下反射的性能问题。搜索一下,不难搜到老赵的这篇文章,下面是一些杂乱的笔记。(建议先看老赵的文章)
看老赵的文章,老赵得到的结果是这样的:
而我把代码搞下来自己运行得到这样的结果:
这里不是说机器性能造成绝对的时间,而是差距比例完全不一样,想了一阵想起了老赵当时应该是基于.Net3.5,果断把程序的目标框架切换到.Net3.5,结果如下:
三者的差距仍然有些不一样,老赵那边的直接调用与动态执行同一数量级的结果还是没有。但发现了另一些信息。反射和直接调用方法.Net4.0比.Net3.5有非常大的改善,特别是反射,性能提升了好几倍。反而构建表达式树动态调用的方式性能比.Net3.5差了一点。但是相对反射还是有差距,按照这个比例,写写表达式树还是值得的。
老赵的那篇的文章的思路是使用DynamicMethodExecutor来构造一个万能的委托Func<object, object[], object>其中第一个参数是实例对象,第二是参数列表,第三是返回值。.Net4.0的表达式树要比3.5的先进一点,经过一番改造发现是不需要这么一个万能委托的,直接用Expression.Lambda.Compile()编译出来的Delegate强制转换为强类型的委托来得更加简单。全部代码一个方法即可,精简了许多。
使用时转换为强类型的委托即可:
老赵那个委托都是object,使用时的类型转换,还有装箱,拆箱都会有一定的性能损失,而强类型就没有这个问题。首先在老赵的那篇文章上一个方法改为两个方法,然后测试:
结果:
差距不大,但是还是有一定得改善,特别参数是int的方法,用了强类型后性能比较稳定,不会出现偏差。
既然有动态调用方法,同样也可以动态赋值,而且据我的经验,根据PropertyInfo的SetValue去反射设属性值用得比反射调用方法更加频繁。所以同样需要有方法来动态构建委托改善性能。幸好,.Net4.0提供了支持,.Net4.0新增了Expression.Assign来表示一个赋值表达式。有了它,构建起来比方法的更加简单:
直接返回了强类型的委托,所以使用起来更加简单:
来测试一下性能:
结果如下:
虽然跟直接赋值不能比,但比反射快大概30倍。
我把上面的方法用在项目中才发现陷入了一个悖论。就是往往需要使用反射的上下文中是没有实例类型的,而有了实例类型的上下文中有往往不需要反射。所以构建表达式树是需要去掉实例的类型参数,在表达式树中做类型转换,这样会有一点点的性能损失,但同时又带来一个好处,使用时类型参数少了一个,写起来方便了一点。两个主要代码如下:
原文:/article/5272771.html
.Net4.0反射性能改善
看老赵的文章,老赵得到的结果是这样的:
改善老赵的DynamicMethodExecutor
老赵的那篇的文章的思路是使用DynamicMethodExecutor来构造一个万能的委托Func<object, object[], object>其中第一个参数是实例对象,第二是参数列表,第三是返回值。.Net4.0的表达式树要比3.5的先进一点,经过一番改造发现是不需要这么一个万能委托的,直接用Expression.Lambda.Compile()编译出来的Delegate强制转换为强类型的委托来得更加简单。全部代码一个方法即可,精简了许多。
构建委托动态赋值
既然有动态调用方法,同样也可以动态赋值,而且据我的经验,根据PropertyInfo的SetValue去反射设属性值用得比反射调用方法更加频繁。所以同样需要有方法来动态构建委托改善性能。幸好,.Net4.0提供了支持,.Net4.0新增了Expression.Assign来表示一个赋值表达式。有了它,构建起来比方法的更加简单:全部代码
希望对大家有帮助The End。
===重要更新===
我把上面的方法用在项目中才发现陷入了一个悖论。就是往往需要使用反射的上下文中是没有实例类型的,而有了实例类型的上下文中有往往不需要反射。所以构建表达式树是需要去掉实例的类型参数,在表达式树中做类型转换,这样会有一点点的性能损失,但同时又带来一个好处,使用时类型参数少了一个,写起来方便了一点。两个主要代码如下:相关文章推荐
- 利用表达式树构建委托改善反射性能
- 利用表达式树构建委托改善反射性能
- 利用表达式树构建委托改善反射性能
- .Net4.0用表达式树构建委托改善反射性能
- .NET中反射机制的使用与分析 分类: .NET 2014-02-17 15:51 346人阅读 评论(0) 收藏
- Socket一对多。。利用Socket发送命令给客户机让其执行关机命令 分类: .NET 2010-10-22 18:00 1768人阅读 评论(0) 收藏
- C# 中的委托和事件 分类: .NET 接口+泛型+委托+继承 2011-08-30 10:09 20人阅读 评论(0) 收藏 举报 引言 委托 和 事件在 .Net Framework中的应用非
- 利用Windows性能计数器(PerformanceCounter)监控 分类: windows驱动程序WDM VC++ 2015-03-10 10:44 369人阅读 评论(0) 收藏
- 关于sql连接语句中的Integrated Security=SSPI 分类: .NET 2015-07-13 11:45 9人阅读 评论(0) 收藏
- 支持同步滚动的RichTextbox控件 分类: .NET 2013-04-23 13:00 416人阅读 评论(1) 收藏
- 删除IE下所有临时文件 分类: .NET 2012-05-02 13:45 390人阅读 评论(0) 收藏
- iOS学习笔记之内存管理及@property 分类: ios开发 2015-05-15 10:34 174人阅读 评论(0) 收藏
- python性能优化摘录 分类: python 2013-01-17 18:01 1192人阅读 评论(0) 收藏
- Python编程规范及性能优化三 分类: python 2013-01-18 18:04 207人阅读 评论(0) 收藏
- c# treeview 年月日 分类: .NET 2012-12-17 18:02 501人阅读 评论(0) 收藏
- .net zip压缩包装类 分类: .NET 2013-11-26 10:53 624人阅读 评论(0) 收藏
- python性能优化摘录(二) 分类: python 2013-01-18 11:27 291人阅读 评论(0) 收藏
- 利用ffmpeg将H264流 解码为RGB 分类: VC++ ffmpeg-SDL-VLC-Live555 2015-08-07 11:39 155人阅读 评论(0) 收藏
- c# 将日志文件显示在RichTextBox控件里 分类: .NET 2012-12-18 15:54 722人阅读 评论(0) 收藏
- Hangover 分类: POJ 2015-06-11 10:34 12人阅读 评论(0) 收藏