[C#] 谨慎使用DynamicInvoke

Delegate类提供了一个变参接口DynamicInvoke(params object[] args),可以在委托的具体类型不可知的情况下通过反射来进行委托调用。很方便,但由于变参,而且使用了反射,对性能有极大的影响。

设计实验:

定义一个委托(委托实例函数的内容为空,这个实验仅为检验调用开销,所以去掉了函数体,以避免额外干扰),对这个委托以不同的方式调用8×1024×1024次。

方案1——在明确委托类型的情况下直接调用委托

方案2——事先用一个Delegate变量承接委托实例,然后通过Delegate的DynamicInvoke方法调用委托

方案3——事先从委托中取出要调用的MethodInfo,然后通过MethodInfo的Invoke方法来调用委托

结果:方案1  约70ms,方案2  约8500ms ,方案3  约7500ms

很明显,在确定委托类型的情况下调用委托,就只有一次函数调用的开销,而通过Delegate类的DynamicInvoke反射调用委托就有了太多太多额外开销,事先获取委托的MethodInfo可以减少DynamicInvoke查找方法的那部分开销,但是同确定类型时的委托调用效率还是无法相比。另外方案3中在调用MethodInfo的Invoke方法前还做了一次参数到object[]数组的转化。因为Invoke方法只接受object[]参数,把这一步省掉的话,方案3的消耗可以降到6500ms左右,有好转,但不多。

所以,在能够确定委托类型的情况还是不要贪图方便使用Delegate的DynamicInvoke来代替正常的委托调用。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值