比较一下以“反射”和“表达式”执行方法的性能差异
2023-09-27 14:27:55 时间
由于频繁地使用反射会影响性能,所以ASP.NET MVC采用了表达式树的方式来执行目标Action方法。具体来说,ASP.NET MVC会构建一个表达式来体现针对目标Action方法的执行,并且将该表达式编译成可执行代码。编译后的可执行代码体现为一个委托对象,该委托对象会被缓存起来以用于针对同一个Action方法的执行。为了让大家能够和直观地理解两种(直接利用反射和利用表达式编译后的委托对象)方法执行在性能上的差异,我们来做一个简单的实例演示。我们在一个控制台应用中定义了如下一个Foobar类型,它的Invoke方法就是我们需要测试的目标方法。简单起见,我们没有为它定义任何参数,方法本身也不需要执行任何具体操作。
1: public class Foobar
具体的测试程序如下所示。三个静态属性Target、Method和Executor分别代表执行的目标对象、目标方法和表达式编译后生成的委托对象,后者通过调用静态方法CreateExecutor方法创建。
12: ParameterExpression target = Expression.Parameter(typeof(Foobar),"target");
14: return Expression.Lambda Action Foobar (expression, target).Compile();
26: Console.WriteLine("{0,-10}{1,-12}{2}", "Times", "Reflection", "Expression");
测试方法Test的参数times表示我们执行目标方法的次数。在该方法中,我们调用MethodInfo对象的Invoke方法以反射的形式执行目标方法,然后利用Executor属性表示的委托对象来执行目标方法,并将它们执行的时间(以毫秒为单位)输出来。在作为程序入口的Main方法中,我们先后三个调用Test方法,并将执行目标方法的次数分别设置为100,000(十万)、1,000,000(百万)和10,000,000(千万)。运行程序后我们会在控制台上得到如下所示的输出结果,可以看出直接采用反射方式执行某个方法确实在性能上要差一些,但是差异其实不算明显。很多人总是觉得在程序中使用反射会对性能造成很大的影响,其实在我看来在很多情况下反射本身都不是造成性能瓶颈的元凶。
微信公众账号:大内老A
微博:www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 原文链接
字节码编程,Byte-buddy篇二《监控方法执行耗时动态获取出入参类型和值》 在前面的ASM、Javassist 章节中也有陆续实现过获取方法的出入参信息,但实现的方式还是偏向于字节码控制,尤其ASM,更是需要使用到字节码指令将入参信息压栈操作保存到局部变量用于输出,在这个过程中需要深入了解Java虚拟机规范,否则很不好完成这一项的开发。但!ASM也是性能最牛的。其他的字节码编程框架都是基于它所开发的。
相关文章
- 5种kafka消费端性能优化方法
- <转>MySQL性能调优的10个方法
- 测脉冲频率几种方法的比较
- MySQL数据性能优化-修改方法与步骤
- Spring Cloud Feign 使用方法与性能优化
- 【性能测试】性能测试基本原则与方法
- ElasticSearch from + size 分页查询过程分析,及其官方ES深度分页性能优化方法
- Mysql并发时经典常见的死锁原因及解决方法
- 10方法改善虚拟服务器的存储性能
- [日常工作]GS使用消息队列进行凭证实时记账 提高性能配置方法
- 【ChatGPT】大模型原理学习:详解 Transformers 的性能优化的 8 种方法
- sun.misc.BASE64Encoder找不到jar包的解决方法
- 【GoLang】GoLang 单元测试、性能测试使用方法
- js创建函数的方法
- 什么是性能调优?性能调优的方法有哪些,流程是怎样的
- Java 成员方法的定义
- win10开卓越性能模式方法
- Python pandas.DataFrame.reset_index函数方法的使用
- 4种提高多维数据分析的方法
- 不要再用main方法测试代码性能了,用这款JDK自带工具
- C# 7.2 通过 in 和 readonly struct 减少方法值复制提高性能
- 漫话性能:USE方法
- python中PIL.Image和opencv处理图像方法及区别
- 【并发编程008】调用共享对象的notify()方法后, 会唤醒一个在该共享变量上调用wait()的线程, 说说两个线程对锁的获取释放过程?