优化委托的 DynamicInvoke

Intro

委托方法里有一个 DynamicInvoke 的方法,可以在不清楚委托实际类型的情况下执行委托方法,但是用 DynamicInvoke 去执行的话会比直接用 Invoke 的方法会慢上很多,差了两个数量级,所以在知道委托类型的情况下尽可能使用 Invoke 执行,但有时候我们并不知道委托的实际类型,比如在很多类库项目中可能并不是强类型的委托

优化方法

优化方法,直接执行委托的对应的方法,DynamicInvoke 实际也是调用的对应的方法,我们如果执行调用对应的方法就可以优化

  1. delegate func = (Func<string, string>)str=> "12345";
  2. string paramString = "321";
  3. // Invoke
  4. ((Func<string, string>)func).Invoke(paramString);
  5. // DynamicInvoke
  6. func.DynamicInvoke(new object[]{ paramString });
  7. // Method Invoke
  8. func.Method.Invoke(func.Target, new object[]{ paramString });

性能测试

下面做一个性能测试,测试代码如下:

  1. public class DelegateInvokeTest
  2. {
  3. private readonly Delegate _func, _func1;
  4. private readonly string parameter;
  5. private readonly int paramInt;
  6. public DelegateInvokeTest()
  7. {
  8. parameter = "Test";
  9. paramInt = 1;
  10. _func = (Func<string, string>)(str => str);
  11. _func1 = (Func<int, int>)(val => 0);
  12. }
  13. [Benchmark(Baseline = true)]
  14. public object Invoke()
  15. {
  16. return ((Func<string, string>)_func).Invoke(parameter);
  17. }
  18. [Benchmark]
  19. public object InvokeBoxing()
  20. {
  21. return ((Func<int, int>)_func1).Invoke(paramInt);
  22. }
  23. [Benchmark]
  24. public object DynamicInvoke()
  25. {
  26. return _func.DynamicInvoke(parameter);
  27. }
  28. [Benchmark]
  29. public object DynamicInvokeBoxing()
  30. {
  31. return _func1.DynamicInvoke(paramInt);
  32. }
  33. [Benchmark]
  34. public object MethodInfoInvoke()
  35. {
  36. return _func.Method?.Invoke(_func.Target, new object[] { parameter });
  37. }
  38. [Benchmark]
  39. public object MethodInfoInvokeBoxing()
  40. {
  41. return _func1.Method?.Invoke(_func1.Target, new object[] { paramInt });
  42. }
  43. [Benchmark]
  44. public object ReflectInvoke()
  45. {
  46. var funcType = typeof(Func<,>).MakeGenericType(typeof(string), typeof(string));
  47. var method = funcType.GetProperty("Method")?.GetValueGetter()?.Invoke(_func) as MethodInfo;
  48. var target = funcType.GetProperty("Target")?.GetValueGetter()?.Invoke(_func);
  49. return method?.Invoke(target, new object[] { parameter });
  50. }
  51. [Benchmark]
  52. public object ReflectInvokeBoxing()
  53. {
  54. var funcType = typeof(Func<,>).MakeGenericType(typeof(string), typeof(int));
  55. var method = funcType.GetProperty("Method")?.GetValueGetter()?.Invoke(_func1) as MethodInfo;
  56. var target = funcType.GetProperty("Target")?.GetValueGetter()?.Invoke(_func1);
  57. return method?.Invoke(target, new object[] { paramInt });
  58. }
  59. }

测试结果如下:

由上面的结果,我们可以看出来,直接调用方法的性能虽然还是比 Invoke 慢上好多,但是相比 DynamicInvoke 已经优化 70% 左右,对于有装箱操作的性能会稍差一些,比 DynamicInvoke 优化可达 44% 左右。

Reference

委托的 `DynamicInvoke` 小优化的更多相关文章

  1. SPFA 小优化*2

    /* bzoj 2763 SPFA小优化 循环队列+SLF 顺面改掉自己之前手打qeueu的坏毛病*/ #include<iostream> #include<cstring> ...

  2. 缓存 Array.length 是老生常谈的小优化

    问题 缓存 Array.length 是老生常谈的小优化. // 不缓存 for (var i = 0; i < arr.length; i++) { ... } // 缓存 var len = ...

  3. [MySQL5.6] 最近对group commit的小优化

    [MySQL5.6] 最近对group commit的小优化 http://www.tuicool.com/articles/rEZr2q 最近花了一些时间在做MySQL Group Commit的优 ...

  4. SPFA的小优化

    标签:闲扯 SPFA的小优化 1. 向队尾加入元素时,如果它比对首还优,就把把它直接和队首交换. 拿一个双端队列来实现 (手写 , head ,tail   STLdeque亲测及其慢) 这个小优化其 ...

  5. KMP算法的正确性证明及一个小优化

    直接把作业帖上来是不是有点不太公道呀... 无所谓啦反正各位看着开心就行 KMP算法 对于模式串$P$,建立其前缀函数$ N$ ,其中$N [q] $ 表示在$P$中,以$q$位置为结束的可以匹配到前 ...

  6. js代码小优化

    今天真坑,老大请了两天假,来了之后指指点点,不过人家说的倒是很是到位 好不容易把嵌套小窗口登陆注册功能,做完了,直接调之前写好的登陆注册功能,也就是页面跳转 并不是ajax异步登陆 说让改成ajax ...

  7. HDU 5884 Sort(2016年青岛网络赛 G 二分+贪心+小优化)

    好题 题意:给你n<=100000个数,每个数范围[0,1000],然后给你一个最大的代价T,每次最多合并k个数成为一个数,代价为k个数的总和.问最后合成1个数的总代价不大于T的最小k 题解:我 ...

  8. Centos7安装完成后一些小优化

    1.修改ip地址.网关.主机名.DNS等 [root@localhost ~]# vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 #网 ...

  9. UWP自动填充控件AutoSuggestBox小优化

    UWP提供的AutoSuggestBox本身非常好用,在项目中经常用到,但是当我们使用时发现一下不人性化的设置,例子1如下: <Page x:Class="SelfInkCanvas. ...

随机推荐

  1. pandas 的常用方法

    pandas的常用方法: 1.数据输入 2.数据查看 3.数据清洗 4.数据处理 5.数据提取 6.数据筛选 7.数据汇总 8.数据统计 9.数据输出 详情见: https://blog.csdn.n ...

  2. Django魔法

    (●'◡'●)

  3. BIT-Count of Range Sum

    2019-12-17 18:56:56 问题描述: 问题求解: 本题个人感觉还是很有难度的,主要的难点在于如何将题目转化为bit计数问题. 首先构建一个presum数组,这个没有问题. 需要对于任意一 ...

  4. Ruby使用记录

    1.首先,重要的事情说三遍,不用在Windows里开发Ruby 1.第一次在windows里安装ruby,装的最新版,当时就遇到了很奇怪的编码问题,如运行命令gem install xxx,提示编码错 ...

  5. SpringBoot项目中应用Jedis和一些常见配置

    优雅的使用Jedis Redis的Java客户端有很多,Jedis是其中使用比较广泛和性能比较稳定的一个.并且其API和RedisAPI命名风格类似,推荐大家使用 在项目中引入Jedis 可以通过Ma ...

  6. java两数相乘基础算法

    下面是别人给我的代码: package com.bootdo; public class Test { public static void main(String[] args) { System. ...

  7. Building Applications with Force.com and VisualForce(Dev401)(十九):Visualforce Pages: Visualforce Componets (Tags)

    Dev401-020:Visualforce Pages: Visualforce Componets (Tags) Module Agenda1.Tag Basics2.Tag Bindings T ...

  8. DrQA 阅读维基百科来回答开放问题 Reading Wikipedia to Answer Open-Domain Questions

    DrQA 是一个阅读理解系统用在开放领域问答.特别的,DrQA 针对一个机器阅读任务.在这个列表里,我们为一个潜在非常大的预料库中搜索一个问题的答案.所以,这个系统必须结合文本检索和机器文本理解. 项 ...

  9. 使用条件随机场模型解决文本分类问题(附Python代码)

    对深度学习感兴趣,热爱Tensorflow的小伙伴,欢迎关注我们的网站!http://www.tensorflownews.com.我们的公众号:磐创AI. 一. 介绍 世界上每天都在生成数量惊人的文 ...

  10. mysql之日志

    我是李福春,我在准备面试,今天的题目是: mysql的redolog和binlog有什么区别? 答: 如下面的表格, redolog vs binlog 然后我们扩展一下,因为日志主要是记录的修改日志 ...