比较一下以“反射”和“表达式”执行方法的性能差异
由于频繁地使用反射会影响性能,所以ASP.NET MVC采用了表达式树的方式来执行目标Action方法。具体来说,ASP.NET MVC会构建一个表达式来体现针对目标Action方法的执行,并且将该表达式编译成可执行代码。编译后的可执行代码体现为一个委托对象,该委托对象会被缓存起来以用于针对同一个Action方法的执行。为了让大家能够和直观地理解两种(直接利用反射和利用表达式编译后的委托对象)方法执行在性能上的差异,我们来做一个简单的实例演示。我们在一个控制台应用中定义了如下一个Foobar类型,它的Invoke方法就是我们需要测试的目标方法。简单起见,我们没有为它定义任何参数,方法本身也不需要执行任何具体操作。
1: public class Foobar
2: {
3: public void Invoke(){}
4: }
具体的测试程序如下所示。三个静态属性Target、Method和Executor分别代表执行的目标对象、目标方法和表达式编译后生成的委托对象,后者通过调用静态方法CreateExecutor方法创建。
1: class Program
2: {
3:
4: public static Foobar Target { get; private set; }
5: public static MethodInfo Method { get; private set; }
6: public static Action<Foobar> Executor { get; private set; }
7:
8: private static object[] args = new object[0];
9:
10: private static Action<Foobar> CreateExecutor(MethodInfo method)
11: {
12: ParameterExpression target = Expression.Parameter(typeof(Foobar),"target");
13: Expression expression = Expression.Call(target, method);
14: return Expression.Lambda<Action<Foobar>>(expression, target).Compile();
15: }
16:
17: static Program()
18: {
19: Target = new Foobar();
20: Method = typeof(Foobar).GetMethod("Invoke");
21: Executor = CreateExecutor(Method);
22: }
23:
24: static void Main()
25: {
26: Console.WriteLine("{0,-10}{1,-12}{2}", "Times", "Reflection", "Expression");
27: Test(100000);
28: Test(1000000);
29: Test(10000000);
30: }
31:
32: private static void Test(int times)
33: {
34: Stopwatch stopwatch = new Stopwatch();
35:
36: stopwatch.Start();
37: for (int i = 0; i < times; i++)
38: {
39: Method.Invoke(Target, args);
40: }
41: long elapsed1 = stopwatch.ElapsedMilliseconds;
42:
43: stopwatch.Restart();
44: for (int i = 0; i < times; i++)
45: {
46: Executor(Target);
47: }
48: long elapsed2 = stopwatch.ElapsedMilliseconds;
49:
50: Console.WriteLine("{0,-10}{1,-12}{2}", times, elapsed1, elapsed2);
51: }
52: }
测试方法Test的参数times表示我们执行目标方法的次数。在该方法中,我们调用MethodInfo对象的Invoke方法以反射的形式执行目标方法,然后利用Executor属性表示的委托对象来执行目标方法,并将它们执行的时间(以毫秒为单位)输出来。在作为程序入口的Main方法中,我们先后三个调用Test方法,并将执行目标方法的次数分别设置为100,000(十万)、1,000,000(百万)和10,000,000(千万)。运行程序后我们会在控制台上得到如下所示的输出结果,可以看出直接采用反射方式执行某个方法确实在性能上要差一些,但是差异其实不算明显。很多人总是觉得在程序中使用反射会对性能造成很大的影响,其实在我看来在很多情况下反射本身都不是造成性能瓶颈的元凶。
1: Times Reflection Expression
2: 100000 34 2
3: 1000000 273 28
4: 10000000 2627 284
比较一下以“反射”和“表达式”执行方法的性能差异的更多相关文章
- js 将字符串当作js表达式执行方法
听同事说了一个需求.他有一个数据对象obj,接口会给他返回一个索引key,这个key长度不固定,根据这个key去修改obj对应的值. 举个例子: let obj={"level1" ...
- 使用Java反射优化多个方法调用
有段时间没来写博客了,心里一直念叨空了来,今天有时间来记录一篇.前段时间领导提出优化部分系统模块,根据业务要求系统中有很多产品,产品下面有N个指标,一个指标就对应一个方法,所以系统代码中就是这样一个情 ...
- CASE函数 sql server——分组查询(方法和思想) ref和out 一般处理程序结合反射技术统一执行客户端请求 遍历查询结果集,update数据 HBuilder设置APP状态栏
CASE函数 作用: 可以将查询结果集的某一列的字段值进行替换 它可以生成一个新列 相当于switch...case和 if..else 使用语法: case 表达式/字段 when 值 then ...
- Java反射、动态加载(将java类名、方法、方法参数当做参数传递,执行方法)
需求:将java类名.方法.方法参数当做参数传递,执行方法.可以用java的动态加载实现 反射的过程如下: 第一步:通过反射找到类并创建实例(classname为要实例化的类名,由pack ...
- Day16_88_通过反射机制执行方法
通过反射机制执行方法 * method.invoke(object,"admin","123"); * 代码 import java.lang.reflect. ...
- kettle job如何利用java的反射机制获取执行的sql语句
kettle job中的JavaScript如何获取同一个job中SQL步骤的执行语句并让执行语句记录在日志中呢?首先写日志需要用到job中JavaScript写日志的方法,其次是利用java反射机制 ...
- 通过spring来配置某个命令号和执行方法之间的映射
整理的内容 1.手动获取spring的ApplicationContext和bean对象 写一个工具类实现ApplicationContextAware接口 2.反射的知识整理 3.前后端协议交互的时 ...
- day27:反射和双下方法
1, # 面向对象的三大特性:继承,多态和封装 # 继承: # 单继承: **** # 父类(超类,基类) # 子类(派生类) 派生方法和派生属性 # 子类的对象在调用方法和属性:先用自己的,自己没有 ...
- Java 8-Lambda表达式、方法引用、标准函数接口与流操作、管道操作之间的关系
1.Lambda表达式与接口之间的关系 只要Lambda表达式的声明形式与接口相一致,在很多情况下都可以替换接口.见如下代码 Thread t1 = new Thread(new Runnable() ...
随机推荐
- 【BZOJ3156】防御准备 斜率优化DP
裸题,注意:基本的判断(求Min还是Max),因为是顺着做的,且最后一个a[i]一定要取到,所以是f[n]. DP:f[i]=min(f[j]+(i-j-1)*(i-j)/2+a[i]) 依旧设x&g ...
- jpeg相关知识
一.jpeg介绍 JPEG 是 Joint Photographic Exports Group 的英文缩写,中文称之为联合图像专家小组.该小组隶属于 ISO 国际标准化组织,主要负责定制静态数字图像 ...
- 前端页面开发,最低兼容IE 8的多设备跨平台问题解决!
项目要求: 网站能够使用PC.ipad.mobile phone正常访问 页面PSD版式宽度分别为1024px和750px 参考资料 使用CSS3 Media Queries,其作用就是允许添加表达式 ...
- Mysql 表分区
是否支持分区:mysql> show variables like '%partition%';+-----------------------+-------+| Variable_name ...
- SQL Server 2012基本知识
1:图形化界面设置外键 解决:table->选中表->design->选中需要设置外键的字段->选择"关系"->选择"添加"-&g ...
- Android控件之Notification
Android通知就是让设备在屏幕最顶上那栏里面显示图标,当滑下通知栏之后可以看到列表状的通知选项,有些是"通知"类型的,有些是"正在运行"类型的," ...
- nlp
http://blog.sina.com.cn/s/blog_574a437f01019poo.html
- CGI和ISAPI
1) CGI概念CGI即通用网关接口(Common Gateway Interface),它是一段程序,运行在服务器上,提供同客户端HTML页面的交互,通俗的讲CGI就象是一座桥,把网页和WEB服务器 ...
- sublime text 如何新建,删除,重命名等问文件的快速操作
引用自: stackoverflow 可以使用插件, Sidebar Enhancements, 按ctrl+shift+p 输入install package回车 搜索该插件后即可完成
- Zero Copy I: User-Mode Perspective
By now almost everyone has heard of so-called zero-copy functionality under Linux, but I often run i ...