委托的 `DynamicInvoke` 小优化
优化委托的 DynamicInvoke
Intro
委托方法里有一个 DynamicInvoke
的方法,可以在不清楚委托实际类型的情况下执行委托方法,但是用 DynamicInvoke
去执行的话会比直接用 Invoke
的方法会慢上很多,差了两个数量级,所以在知道委托类型的情况下尽可能使用 Invoke
执行,但有时候我们并不知道委托的实际类型,比如在很多类库项目中可能并不是强类型的委托
优化方法
优化方法,直接执行委托的对应的方法,DynamicInvoke
实际也是调用的对应的方法,我们如果执行调用对应的方法就可以优化
delegate func = (Func<string, string>)str=> "12345";
string paramString = "321";
// Invoke
((Func<string, string>)func).Invoke(paramString);
// DynamicInvoke
func.DynamicInvoke(new object[]{ paramString });
// Method Invoke
func.Method.Invoke(func.Target, new object[]{ paramString });
性能测试
下面做一个性能测试,测试代码如下:
public class DelegateInvokeTest
{
private readonly Delegate _func, _func1;
private readonly string parameter;
private readonly int paramInt;
public DelegateInvokeTest()
{
parameter = "Test";
paramInt = 1;
_func = (Func<string, string>)(str => str);
_func1 = (Func<int, int>)(val => 0);
}
[Benchmark(Baseline = true)]
public object Invoke()
{
return ((Func<string, string>)_func).Invoke(parameter);
}
[Benchmark]
public object InvokeBoxing()
{
return ((Func<int, int>)_func1).Invoke(paramInt);
}
[Benchmark]
public object DynamicInvoke()
{
return _func.DynamicInvoke(parameter);
}
[Benchmark]
public object DynamicInvokeBoxing()
{
return _func1.DynamicInvoke(paramInt);
}
[Benchmark]
public object MethodInfoInvoke()
{
return _func.Method?.Invoke(_func.Target, new object[] { parameter });
}
[Benchmark]
public object MethodInfoInvokeBoxing()
{
return _func1.Method?.Invoke(_func1.Target, new object[] { paramInt });
}
[Benchmark]
public object ReflectInvoke()
{
var funcType = typeof(Func<,>).MakeGenericType(typeof(string), typeof(string));
var method = funcType.GetProperty("Method")?.GetValueGetter()?.Invoke(_func) as MethodInfo;
var target = funcType.GetProperty("Target")?.GetValueGetter()?.Invoke(_func);
return method?.Invoke(target, new object[] { parameter });
}
[Benchmark]
public object ReflectInvokeBoxing()
{
var funcType = typeof(Func<,>).MakeGenericType(typeof(string), typeof(int));
var method = funcType.GetProperty("Method")?.GetValueGetter()?.Invoke(_func1) as MethodInfo;
var target = funcType.GetProperty("Target")?.GetValueGetter()?.Invoke(_func1);
return method?.Invoke(target, new object[] { paramInt });
}
}
测试结果如下:
由上面的结果,我们可以看出来,直接调用方法的性能虽然还是比 Invoke
慢上好多,但是相比 DynamicInvoke
已经优化 70% 左右,对于有装箱操作的性能会稍差一些,比 DynamicInvoke
优化可达 44% 左右。
Reference
- https://github.com/WeihanLi/PerformanceTest/blob/master/PerformanceTest/ReflectionTests/DelegateInvokeTest.cs
- https://github.com/WeihanLi/PerformanceTest/blob/master/PerformanceTest/BenchmarkDotNet.Artifacts/results/PerformanceTest.ReflectionTests.DelegateInvokeTest-report-github.md
委托的 `DynamicInvoke` 小优化的更多相关文章
- SPFA 小优化*2
/* bzoj 2763 SPFA小优化 循环队列+SLF 顺面改掉自己之前手打qeueu的坏毛病*/ #include<iostream> #include<cstring> ...
- 缓存 Array.length 是老生常谈的小优化
问题 缓存 Array.length 是老生常谈的小优化. // 不缓存 for (var i = 0; i < arr.length; i++) { ... } // 缓存 var len = ...
- [MySQL5.6] 最近对group commit的小优化
[MySQL5.6] 最近对group commit的小优化 http://www.tuicool.com/articles/rEZr2q 最近花了一些时间在做MySQL Group Commit的优 ...
- SPFA的小优化
标签:闲扯 SPFA的小优化 1. 向队尾加入元素时,如果它比对首还优,就把把它直接和队首交换. 拿一个双端队列来实现 (手写 , head ,tail STLdeque亲测及其慢) 这个小优化其 ...
- KMP算法的正确性证明及一个小优化
直接把作业帖上来是不是有点不太公道呀... 无所谓啦反正各位看着开心就行 KMP算法 对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前 ...
- js代码小优化
今天真坑,老大请了两天假,来了之后指指点点,不过人家说的倒是很是到位 好不容易把嵌套小窗口登陆注册功能,做完了,直接调之前写好的登陆注册功能,也就是页面跳转 并不是ajax异步登陆 说让改成ajax ...
- HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)
好题 题意:给你n<=100000个数,每个数范围[0,1000],然后给你一个最大的代价T,每次最多合并k个数成为一个数,代价为k个数的总和.问最后合成1个数的总代价不大于T的最小k 题解:我 ...
- Centos7安装完成后一些小优化
1.修改ip地址.网关.主机名.DNS等 [root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 #网 ...
- UWP自动填充控件AutoSuggestBox小优化
UWP提供的AutoSuggestBox本身非常好用,在项目中经常用到,但是当我们使用时发现一下不人性化的设置,例子1如下: <Page x:Class="SelfInkCanvas. ...
随机推荐
- 内置函数---filter和map
filter filter()函数接收一个函数 f 和一个list,这个函数 f 的作用是对每个元素进行判断,返回 True或 False,filter()根据判断结果自动过滤掉不符合条件的元素,返回 ...
- Github搜索技巧整理
Github官方网址:https://github.com/ 一.详细官方文档:https://help.github.com/en/github/searching-for-information- ...
- 第十四周java实验作业
实验十四 Swing图形界面组件 实验时间 20178-11-29 1.实验目的与要求 (1) 掌握GUI布局管理器用法: 在java中的GUI应用 程序界面设计中,布局控制通过为容器设置布局管理器 ...
- C语言学生管理系统
想练习一下链表,所以就有了这个用C写的学生管理系统 没有把它写入文件,才不是因为我懒哈哈哈,主要是为了练习链表的 #include<stdio.h> #include<stdlib. ...
- [BFS,大水题] Codeforces 198B Jumping on Walls
题目:http://codeforces.com/problemset/problem/198/B Jumping on Walls time limit per test 2 seconds mem ...
- [转载]float 和 double 的一二三点事
文章转载于博客园作者jillzhang,原文链接http://jillzhang.cnblogs.com/ .文章为jillzhang原创,转载条件请看原文链接. 关于浮点数精度和范围,请看末尾. C ...
- postman设置全局变量及参数化
笔者第一次记录使用过程,仅供参考 测试过程中接口的前缀都是一样的,所以我们可以将这个前缀作为全局变量来使用 首先,打开postman点击这里的小齿轮设置 在这里就可以进行变量的一个添加,添加好之后记住 ...
- 解决pycharm不能导入bs4模块问题
问题描述: 在导入bs4模块时有报错提示 “ Traceback (most recent call last): File "E:/project/code/py-pengfu/py-pf ...
- coding++ :MySQL 使用 SQL 语句查询数据库所有表注释已经表字段注释
1.要查询数据库 "mammothcode" 下所有表名以及表注释 /* 查询数据库 ‘mammothcode’ 所有表注释 */ SELECT TABLE_NAME,TABLE_ ...
- 数据分析_numpy_基础2
数据分析_numpy_基础2 sqrt 开方 arr = np.arange(10) arr # array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) np.sqrt(arr) ...