C# 直接调用vs 委托vs动态调用vs动态类型vs反射,最佳性能测试
懒得解释,自己看代码
测试结果:
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反射,最佳性能测试的更多相关文章
- 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)
反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法) 创建Delegate (1).Delegate.CreateDelegate(Type, ...
- C#动态调用C++编写的DLL函数
C#动态调用C++编写的DLL函数 动态加载DLL需要使用Windows API函数:LoadLibrary.GetProcAddress以及FreeLibrary.我们可以使用DllImport在C ...
- C++调用DLL有两种方法——静态调用和动态调用
C++调用DLL有两种方法——静态调用和动态调用 标签: dllc++winapinullc 2011-09-09 09:49 11609人阅读 评论(0) 收藏 举报 分类: cpp(30) [ ...
- 【C#】 使用Gsof.Native 动态调用 C动态库
[C#] 使用Gsof.Native 动态调用 C动态库 一.背景 使用C# 开发客户端时候,我们经常会调用一些标准的动态库或是C的类库.虽然C# 提供的PInvoke的方式,但因为使用的场景的多变, ...
- 采用异步来实现重新连接服务器或者重新启动服务 C#中类的属性的获取 SignalR2简易数据看板演示 C#动态调用泛型类、泛型方法 asp .net core Get raw request. 从壹开始前后端分离[.NetCore 不定期更新] 38 ║自动初始化数据库
采用异步来实现重新连接服务器或者重新启动服务 开启异步监听,不会导致主线程的堵塞,在服务异常断开后一直检测重新连接服务,成功连接服务后通知各个注册的客户端! #region 检测断线并重连OPC服务 ...
- C#中动态调用DLL动态链接库
其中要使用两个未公开的Win32 API函数来存取控制台窗口,这就需要使用动态调用的方法,动态调用中使用的Windows API函数主要有三个,即:Loadlibrary,GetProcAddress ...
- C#中动态调用DLL动态链接库(转)
本来是想实现控制台程序运行时自动全屏,但是只找到VC下的实现方法(http://www.vckbase.com/bbs/prime/viewprime.asp?id=347). 其中要使用两个未公开的 ...
- 托管非托管Dll动态调用
原文:托管非托管Dll动态调用 最近经常看到有人问托管非托管Dll调用的问题.对于动态库的调用其实很简单.网上很多代码都实现了Dll的静态调用方法.我主要谈论下动态库的动态加载. 对于托管动态库,实现 ...
- C#使用表达式树动态调用方法并实现99乘法表
我们在使用C#编程的时候,经常使用反射来动态调用方法,但有时候需要动态的生成方法,下面介绍使用表达式树的方式来自动生成方法,并调用. 首先需要说明什么是表达式,熟悉Linq的程序猿都用过类似于下面的代 ...
随机推荐
- RTTI 运行时类型识别 及异常处理
RTTI 运行时类型识别 typeid ------ dynamic_cast dynamic_cast 注意事项: 1.只能应用于指针和引用之间的转化 2.要转换的类型中必须包含虚函数 3. ...
- iOS错误总结(三)
1.如果tableView设置为分组的样式(默认是有cell之间的分割线,可以设置颜色),默认有组以及组尾的高度 需要手动在组头组尾的代理方法中进行组高的设置(如果想设置为0,最好写0.01) 2.组 ...
- JS实现动态提示文本框可输入剩余字数(类似发表微博数字提示)
一.实现效果: 为了更直观的体现用户在文本框输入文本时能看到自己输入了多少字,项目中需要通过判断提示文本框剩余可输入字数. html & JS: <div> <textare ...
- 关于yii2框架活动记录activeRecord添加默认字段的问题
平时使用sql的时候可以如下添加默认字段flag: "select a.*,0 as flag from user_info a", 对于yii2框架则需要这样: $query = ...
- Asp.Net MVC4入门指南(4):添加一个模型
在本节中,您将添加一些类,这些类用于管理数据库中的电影.这些类是ASP.NET MVC 应用程序中的"模型(Model)". 您将使用.NET Framework 数据访问技术En ...
- MySQL 5.7系列之sys schema(2)
0.导读 MySQL 5.7引入了sys schema,有了它,我们排查分析一些问题时将更得心应手.sys schema里主要存储的是视图.存储过程.函数等. 视图:用于结果的汇总展示及配置持久化: ...
- winrar命令行加压解密
加密的操作 Rar.exe a -P123 test1.rar test.txt 其中参数a表示添加文件或文件夹到压缩包中,-P参数表示是带密码的加密 Rar.exe e -P123 test1.ra ...
- Crystal Reports拉报表报错:Error detected by database DLL
问题描述: 最近在使用Crystal Reports打印报表时,提示错误信息:"Error detected by database DLL." 如下图: 经查找,是因为数据库名称 ...
- 3G产品升级相关知识
1.3G产品升级时,内核,文件系统,boot,应用程序,全都升级了,是在boot里升的; 2.拨号模式里的 chap:公网; pap:专网 3.用来查看U盘挂在哪个目录下: cat /proc/par ...
- 交换机的link-dependency链路依赖功能
在生产环境中,如果各主机连接到交换机的1-16端口,交换机的18端口上联到外部网络,如果此时交换机的18端口断掉,在主机端网卡仍然有连接,对于一些网络的配置可能就感知不到外部连接的消失,会有问题(如E ...