比较一下以“反射”和“表达式”执行方法的性能差异
由于频繁地使用反射会影响性能,所以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() ...
随机推荐
- swift初体验
swift是一门类型安全的语言,同样也是基于c语言 那么c语言的一些类型也是实用的,不同的是:swift声明变量和常量是不一样的 let:用来修饰常量:var用来修饰变量 e.g: let num=1 ...
- Difference between WCF and Web API and WCF REST and Web Service
The .Net framework has a number of technologies that allow you to create HTTP services such as Web S ...
- Torch Problems: require some packages doesn't work
I've recently got a problem. require 'cutorch' doesn't work. But it was ok yesterday, although I hav ...
- JSPatch 中 defineClass 中覆盖方法的使用
今天研究了一下JSPatch,发现好神奇好奇妙,感觉这几天我都会乐此不彼的去研究这个高大上的东西. 出处来着:https://github.com/bang590/JSPatch 简单介绍一下这个 d ...
- 基于node.js的压缩合并安装
1.构建工具(grunt,gulp) 下载地址:http://gruntjs.cn/http://gruntjs.com/ (1)安装nodejs(http://www.nodejs.org/) 验证 ...
- Python之路Day20-Django一对一(多)以及Ajax
上节内容回顾 问题一:Django请求生命周期 -> URL对应关系(匹配) -> 视图函数 -> 返回用户字符串-> URL对应关系(匹配) -> 视图函数 -> ...
- Python之路第一课Day5--随堂笔记(模块)
本节课程大纲: 1.模块介绍 2.time &datetime模块 3.random 4.os 5.sys 6.shutil 7.json & picle 8.shelve 9.xml ...
- 一台linux真实机实现多台Tomcat服务
一.事前准备 ü 确保linux并未安装tomcat (这里虚拟机测试) ü 下载jdk与tomcat ① jdk-6u18-ea-bin-b01-linux-i586-20_aug_2009.bin ...
- EditPlus快捷键
Editplus 选中一行: ctrl+rEditplus 复制一行: ctrl+r选择行,然后ctrl+c复制.复制一行到下一行中:Editplus有:Ctrl+j 复制上一行的一个字符到当前行Ed ...
- 移动开发可能用到的css单位
众所周知CSS技术我们虽然很熟悉,在使用的过程却很容易被困住,这让我们在新问题出现的时候变得很不利.随着web继续不断地发展,对于新技术新 解决方案的要求也会不断增长.因此,作为网页设计师和前端开发人 ...