VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > temp > 简明python教程 >
  • 优化委托的 `DynamicInvoke`

优化委托的 DynamicInvoke

Intro#

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

优化方法#

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


	
Copy
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 });

性能测试#

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


	
Copy
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

作者: WeihanLi

出处:https://www.cnblogs.com/weihanli/p/12732737.html

版权:本文采用「CC BY 4.0」知识共享许可协议进行许可。



相关教程