日期:2014-05-17 浏览次数:21100 次
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来代替正常的委托调用。