打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
优化委托的 `DynamicInvoke`

Intro

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

优化方法

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

delegate func = (Func<string, string>)str=> "12345";string paramString = "321";// Invoke((Func<string, string>)func).Invoke(paramString);// DynamicInvokefunc.DynamicInvoke(new object[]{ paramString });// Method Invokefunc.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% 左右。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
LINQ与DLR的Expression tree(5):用lambda表达式表示常见控制结构 (转 rednaxelafx.javaeye.com)
通俗理解反射实质
C#反射技术的相关使用方法
Reflect中MethodInfo使用方法
浅谈C#中常见的委托
不使用反射进行C#属性的运行时动态访问
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服