优化委托的 `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#
作者:weihanli
出处:https://www.cnblogs.com/weihanli/p/12732737.html
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
2019-04-19 asp.net core重新加载应用配置