优化委托的 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310410.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构与算法-- 广度优先打印二叉树

广度优先打印二叉树 题目&#xff1a;从上往下打印出二叉树的每一个节点&#xff0c;同一层节点按照从左到右顺序打印&#xff0c;例如下图中二叉树&#xff0c;依次打印出是8,6,10,5,7,9,11 如上题中二叉树的节点定义我们用之前文章 二叉树实现原理中定义的节点结构。此处提议…

实现一个基于动态代理的 AOP

实现一个基于动态代理的 AOPIntro上次看基于动态代理的 AOP 框架实现&#xff0c;立了一个 Flag&#xff0c; 自己写一个简单的 AOP 实现示例&#xff0c;今天过来填坑了目前的实现是基于 Emit 来做的&#xff0c;后面有时间再写一个基于 Roslyn 来实现的示例效果演示演示代码&…

数据结构与算法-- 二叉树后续遍历序列校验

二叉树后续遍历序列校验 题目&#xff1a;输入一个整数数组&#xff0c;判断改数组是否是某个二叉搜索树的后续遍历结果&#xff0c;如果是返回true否则false&#xff0c;假设输入数组的任意两个数字不相同。 例如输入{5,7,6,9,11,10,8}则返回true&#xff0c;因为这个整数序列…

程序员过关斩将-- 工作好多年可能还未真正了解接口和抽象类

点击上方“蓝字”关注我们菜菜哥&#xff0c;我偷偷出去面试了&#xff0c;然后面试官让我回来等消息那你可能挂了呀&#xff0c;有什么问题没回答上来吗确实有一个问题回答的不太好哎&#xff0c;就是接口和抽象类这个确实是面试官比较爱问的题目之一那能不能说说接口和抽象类…

数据结构与索引-- mysql InnoDB存储引擎索引

索引与算法 索引是我们在应用开发过程中程序数据可开发的一个重要助力。也是一个重要的研究方向&#xff0c;索引太多&#xff0c;应用的性能可能受到影响&#xff0c;如果索引太少&#xff0c;对查询性能又会有制约。我们需要找到一个合适的平衡点&#xff0c;这个对性能至关…

扫盲消息队列 | 消息中间件 | Kafka

先吐槽我真的写技术文章写到怀疑人生&#xff0c;我翻看历史发文记录&#xff0c;只要我一本正经的写的技术文章&#xff0c;都没人看&#xff0c;但是&#xff01;一发闲扯淡的内容&#xff0c;阅读量肯定是技术文的好几倍&#xff08;读者爸爸们别这么搞嘛&#xff09;这说明…

数据结构与索引-- B+树索引

B树索引 上一节中我们讨论的都是B树的数据结构的由来以及他的一些操作&#xff0c;B树索引在本质就是B树在数据库中的一个实现&#xff0c;但是B索引在数据库中有一个特点就是他的高扇出性&#xff0c;因此在数据库中&#xff0c;B树的高度一般是2~3层&#xff0c;也就是对于查…

7种方法帮助企业改进软件维护效率

前言为了更高效地维护软件&#xff0c;同时为新的软件开发创造尽可能多的时间&#xff0c;以下为你介绍一些企业采取的方法和步骤。2019年&#xff0c;Tiedlift&#xff0c;一个开源支持和维护的企业&#xff0c;对软件开发人员进行了一项调查&#xff0c;结果显示&#xff0c;…

数据结构与索引-- mySql索引诡异事件

什么时候使用B树索引 并不是所有查询条件下出现的列都需要添加索引。对于什么时候添加索引&#xff0c;我们通过经验判断&#xff0c;访问表中很少一部分行时候&#xff0c;使用B树索引才有意义。对于性别字段&#xff0c;地区字段&#xff0c;类型字段&#xff0c;他们取值范…

[Java基础]抽象类和接口的区别

抽象类和接口的区别&#xff1a;

async,await执行流看不懂?看完这篇以后再也不会了

昨天有朋友在公众号发消息说看不懂await&#xff0c;async执行流&#xff0c;其实看不懂太正常了&#xff0c;因为你没经过社会的毒打&#xff0c;没吃过牢饭就不知道自由有多重要&#xff0c;没生过病就不知道健康有多重要&#xff0c;没用过ContinueWith就不知道await,async有…

如何分析EFCore引发的内存泄漏

调查实体框架核心中的内存泄漏不要让内存泄漏成为洪水术语“内存泄漏”和“ .NET应用程序”不是经常一起使用。但是&#xff0c;我们最近在一个.NET Core Web应用程序中出现了一系列内存不足异常。事实证明&#xff0c;此问题是由Entity Framework Core中的行为更改引起的&…

数据结构与算法-- 二叉树中和为某一值的路径

二叉树中和为某一值的路径 题目&#xff1a;输入一颗二叉树和一个整数&#xff0c;打印出二叉树中节点值的和为给定值的所有路径。从树的根节点开始往下一只到叶子节点所经过的节点形成一条路径。我们用二叉树节点的定义沿用之前文章中 二叉查找树实现原理定义。如下&#xff…