懒得解释,自己看代码

测试结果:

Direct call:00:00:00.0742191
Delegate Direct:00:00:00.0687487
Method Factory(IL):00:00:00.2015243
Direct IL:00:00:00.1980190
New Type:00:00:00.0860233
Reflection:00:00:02.4178550

using System.Reflection;
using System.Reflection.Emit;
using MoeCard.Emit;
using MoeCard.Reflection; namespace MoeCard.TestConsole
{
public class Program
{
public static void DoSomeThing()
{ }
private static void Main(string[] args)
{
const int loops = 10000000; Stopwatch sw = new Stopwatch(); //General delegation
Action action1 = new Action(DoSomeThing); //Dynamic method
MethodFactory<Action> method = MethodFactory.Create<Action>();//自己写的一个动态方法封装类,不必追究其原理
method.CallMethod(action1).Return();
Action action2 = method.Delegation; //Reflection
MethodInfo doSomething = action1.Method; //Standard Dynamic method
DynamicMethod method2 = new DynamicMethod("DoSomeThing", null, null);
ILGenerator generator = method2.GetILGenerator();
generator.Emit(OpCodes.Call, doSomething);
generator.Emit(OpCodes.Ret);
Action action3 = method2.CreateDelegate(typeof (Action)) as Action; //Type Builder AssemblyName assemblyName = Assembly.GetExecutingAssembly().GetName();//最后这玩意儿胜出
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("DynamicClassModule");
TypeBuilder newTypeBuilder = moduleBuilder.DefineType("NewType");
MethodBuilder methodBuilder = newTypeBuilder.DefineMethod("DoSomeThing", MethodAttributes.Public | MethodAttributes.Static);
generator = methodBuilder.GetILGenerator();
generator.Emit(OpCodes.Call, doSomething);
generator.Emit(OpCodes.Ret);
Type newType = newTypeBuilder.CreateType();
Action action4 = Delegate.CreateDelegate(typeof (Action), newType.GetMethod("DoSomeThing")) as Action; assemblyBuilder.Save("DynamicAssembly.dll"); sw.Restart();
for (int i = loops; i != 0; i--)
{
DoSomeThing();
}
sw.Stop();
Console.WriteLine("Direct call:" + sw.Elapsed); action1();
sw.Restart();
for (int i = loops; i != 0; i--)
{
action1();
}
sw.Stop();
Console.WriteLine("Delegate Direct:" + sw.Elapsed); action2();
sw.Restart();
for (int i = loops; i != 0; i--)
{
action2();
}
sw.Stop();
Console.WriteLine("Method Factory(IL):" + sw.Elapsed); action3();
sw.Restart();
for (int i = loops; i != 0; i--)
{
action3();
}
sw.Stop();
Console.WriteLine("Direct IL:" + sw.Elapsed); action4();
sw.Restart();
for (int i = loops; i != 0; i--)
{
action4();
}
sw.Stop();
Console.WriteLine("New Type:" + sw.Elapsed); sw.Restart();
for (int i = loops; i != 0; i--)
{
doSomething.Invoke(null, null);
}
sw.Stop();
Console.WriteLine("Reflection:" + sw.Elapsed); Console.ReadLine();
}
}
}

  

C# 直接调用vs 委托vs动态调用vs动态类型vs反射,最佳性能测试的更多相关文章

  1. 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)

    反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法)   创建Delegate (1).Delegate.CreateDelegate(Type, ...

  2. C#动态调用C++编写的DLL函数

    C#动态调用C++编写的DLL函数 动态加载DLL需要使用Windows API函数:LoadLibrary.GetProcAddress以及FreeLibrary.我们可以使用DllImport在C ...

  3. C++调用DLL有两种方法——静态调用和动态调用

    C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报  分类: cpp(30)  [ ...

  4. 【C#】 使用Gsof.Native 动态调用 C动态库

    [C#] 使用Gsof.Native 动态调用 C动态库 一.背景 使用C# 开发客户端时候,我们经常会调用一些标准的动态库或是C的类库.虽然C# 提供的PInvoke的方式,但因为使用的场景的多变, ...

  5. 采用异步来实现重新连接服务器或者重新启动服务 C#中类的属性的获取 SignalR2简易数据看板演示 C#动态调用泛型类、泛型方法 asp .net core Get raw request. 从壹开始前后端分离[.NetCore 不定期更新] 38 ║自动初始化数据库

    采用异步来实现重新连接服务器或者重新启动服务 开启异步监听,不会导致主线程的堵塞,在服务异常断开后一直检测重新连接服务,成功连接服务后通知各个注册的客户端! #region 检测断线并重连OPC服务 ...

  6. C#中动态调用DLL动态链接库

    其中要使用两个未公开的Win32 API函数来存取控制台窗口,这就需要使用动态调用的方法,动态调用中使用的Windows API函数主要有三个,即:Loadlibrary,GetProcAddress ...

  7. C#中动态调用DLL动态链接库(转)

    本来是想实现控制台程序运行时自动全屏,但是只找到VC下的实现方法(http://www.vckbase.com/bbs/prime/viewprime.asp?id=347). 其中要使用两个未公开的 ...

  8. 托管非托管Dll动态调用

    原文:托管非托管Dll动态调用 最近经常看到有人问托管非托管Dll调用的问题.对于动态库的调用其实很简单.网上很多代码都实现了Dll的静态调用方法.我主要谈论下动态库的动态加载. 对于托管动态库,实现 ...

  9. C#使用表达式树动态调用方法并实现99乘法表

    我们在使用C#编程的时候,经常使用反射来动态调用方法,但有时候需要动态的生成方法,下面介绍使用表达式树的方式来自动生成方法,并调用. 首先需要说明什么是表达式,熟悉Linq的程序猿都用过类似于下面的代 ...

随机推荐

  1. centos rar安装

    wget http://www.rarsoft.com/rar/rarlinux-x64-5.1.1.tar.gz tar -zxvf rarlinux-x64-5.1.1.tar.gz # cd r ...

  2. dg

    package excel; import java.util.Scanner; public class doExcel { public static void main(String args[ ...

  3. 获取WIFI的SSID和本机IP

    1.获取WIFI的SSID 引入库 #import <SystemConfiguration/CaptiveNetwork.h> ..... ..... // WIFI的名字 + (NSS ...

  4. ORACLE 日常处理办法

    Oracle删除当前用户下所有的表的方法 1.如果有删除用户的权限,则可以: drop user user_name cascade; 加了cascade就可以把用户连带的数据全部删掉. 删除后再创建 ...

  5. Nginx配置upstream实现负载均衡

    如果Nginx没有仅仅只能代理一台服务器的话,那它也不可能像今天这么火,Nginx可以配置代理多台服务器,当一台服务器宕机之后,仍能保持系统可用.具体配置过程如下: 1. 在http节点下,添加ups ...

  6. libxml2 移植 arm9

    准备工作: 1.libxml2软件版本:libxml2-2.6.32.tar.gz 2.交叉编译工具链:arm-none-linux-guneabi 软件安装: 1.设置环境变量: export PA ...

  7. Python Windows环境下安装Python集成开发环境 学习之路(一)

    一.安装下载安装 Python https://www.python.org/ 全部下一步,直接Finish  PyCharm http://www.jetbrains.com/pycharm/ 全部 ...

  8. ZOJ 3705 Applications 模拟

    #pragma comment(linker, "/STACK:1024000000,1024000000") #include<cstdio> #include< ...

  9. <停车卫> 产品需求说明书 version 2.0

    <停车卫> 产品需求说明书 文档版本号: Version 2.0 文档编号: xxxx 文档密级: 归属部门/项目: 产品名: 停车卫 子系统名: 编写人: kina 编写日期: 2015 ...

  10. 升级到VS2012,reportViewer无法使用

    最近公司的开发环境升级到VS2012,为了电脑能够快点,我重装系统,只装VS2012没有装VS2010.这个时候问题来了,原本用VS2010开发的项目用VS2012编译能通过,运行时包下图错: 为了解 ...