Delegate.DynamicInvoke与MethodInfo.Invoke的差异、性能及GC分配对比
MethodInfo.Invoke 与 Delegate.DynamicInvoke 核心对比
本质差异
MethodInfo.Invoke是基于反射元数据的直连调用通道:调用全程依赖MethodInfo本身携带的方法签名、参数约束、目标方法地址信息,直接构造栈帧完成方法执行,不需要依赖中间委托对象。Delegate.DynamicInvoke是已绑定目标的委托实例的动态调用通道:调用时首先要完成委托自身的签名校验,匹配传入参数数组的类型合法性、做必要的运行时类型转换,之后才会触发委托绑定的方法执行。它的调用链路多了一层委托实例的校验适配环节,而非直接从元数据跳转到目标方法。
执行速度对比
普遍实测结果是**MethodInfo.Invoke 执行速度更快**:Delegate.DynamicInvoke 比 MethodInfo.Invoke 多了两层固定开销:
- 重复的签名校验:它既要校验委托本身的参数列表和传入数组的匹配度,这部分逻辑和MethodInfo的元数据校验本质重叠,但执行路径更长
- 更高的适配成本:因为要兼容任意委托的签名差异,参数隐式转换、类型容错的处理逻辑比MethodInfo直连反射的实现更复杂
注:这个对比不涉及强类型委托的直接调用——如果提前明确知道委托的具体签名,直接调用强类型委托的Invoke方法,性能会比前两者高几个数量级,几乎接近原生方法调用速度。
GC 分配对比
两者的公共分配来源完全一致:都是调用时传入的object[]参数数组,以及值类型参数装箱产生的临时对象。
但整体来看**Delegate.DynamicInvoke 的GC分配量普遍高于 MethodInfo.Invoke**:
除了上述公共分配外,Delegate.DynamicInvoke 内部还会产生额外的临时开销:包括参数类型校验的上下文对象、动态类型转换生成的临时封装,部分.NET版本中还会因为动态绑定逻辑生成少量托管适配对象,整体分配量通常是同场景下MethodInfo.Invoke的1.2~2倍。
内容的提问来源于stack exchange,提问作者genaray
相关产品推荐
相关产品推荐

