优化委托的 `DynamicInvoke`
程序员文章站
2022-09-26 21:04:26
优化委托的 Intro 委托方法里有一个 的方法,可以在不清楚委托实际类型的情况下执行委托方法,但是用 去执行的话会比直接用 的方法会慢上很多,差了两个数量级,所以在知道委托类型的情况下尽可能使用 执行,但有时候我们并不知道委托的实际类型,比如在很多类库项目中可能并不是强类型的委托 优化方法 优化方 ......
优化委托的 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
上一篇: 来自广东人民的求饶