百科问答小站 logo
百科问答小站 font logo



c#中,is或者as做类型转换是否影响效率,有必要缓存吗? 第1页

  

user avatar   hex-33 网友的相关建议: 
      

首先回答一个问题:is/as 关键字是通过CLR中的 isinst 指令实现,而非反射。

isinst 在当下CoreCLR实现中,对于引用以及值类型,JIT会生成代码调用CoreCLR内部的FCall方法 JIT_IsInstanceOfClass_PortableJIT_IsInstanceOfClass ,而对于接口类型的断定会调用JIT_IsInstanceOfInterface_PortableJIT_IsInstanceOfInterface

这里以 JIT_IsInstanceOfClass_Portable 为例:

       HCIMPL2(Object*, JIT_IsInstanceOfClass_Portable, MethodTable* pTargetMT, Object* pObject) {     FCALL_CONTRACT;     //对传入对象引用判空     if (NULL == pObject)     {         return NULL;     }     //获取对象本身的MethodTable     PTR_VOID pMT = pObject->GetMethodTable();     //遍历继承链,试图比较是否有相等的类型     do {         if (pMT == pTargetMT)             return pObject;          pMT = MethodTable::GetParentMethodTableOrIndirection(pMT);     } while (pMT);     //判断是否有类型等效     if (!pObject->GetMethodTable()->HasTypeEquivalence())     {         return NULL;     }      ENDFORBIDGC();     return HCCALL2(JITutil_IsInstanceOfAny, CORINFO_CLASS_HANDLE(pTargetMT), pObject); }      

可以看到整个流程相当简单,核心就是获取对象的MethodTable在继承链上与目标MethodTable比较。一般来说只要继承链不是很长,都不会存在过多的Overhead。

当然其中另一个因素是FCall本身就是为托管代码对Runtime内部高性能方法调用所设计的:

  1. 其参数顺序遵循JIT的调用约定,无需调整参数顺序。
  2. 与比普通P/Invoke(也就是NDirectCall)更加简单,不存在对参数的Check与Marshaling

综合上面两点,对 isinst 指令JIT生成的不过仅是简单的参数传递与一个call而已,Overhead不成大问题。

附:对代码

JIT为 isinst 指令生成的本机代码(x86)为

为了验证我们的猜想,进行实验对比:

对总是使用as

缓存as结果

10000次重复流程中,缓存as结果得到的时间消耗大概为3.4~3.7ms

而直接使用as不相上下,时间消耗大概为3.3~3.6ms

因此在最后我们可以得出结论,是否缓存as对运行时间的影响是无关痛痒的。

应评论要求用Stopwatch包裹住for循环,循环次数增加到一千万,总是使用as的时间消耗在40~50ms,而使用缓存策略则在100~110ms(带反转)就不放图了,懒。


user avatar   ikkiz-70 网友的相关建议: 
      

仅仅是没有新消息热度下降了而已。想喷的人即使系统成了也会换个角度喷并且否认或者无视自己之前的错误论断,并且以之前得到错误论断同样的方法论基于新的信息得出新的论断,这样又可以开开心心的喷一阵子。




  

相关话题

  工厂模式(factory Method)的本质是什么?为什么引入工厂模式? 
  C 语言线程间怎么通信? 
  求助,大一学Java还是C#? 
  面向对象中接口应该更抽象还是更具象? 
  C#委托的性能开销具体在哪里,有哪些使用指导? 
  Java设计出checked exception有必要吗? 
  大龄门外汉如何进入软件开发行业? 
  C# 的匿名类型为什么要限制属性为只读呢? 
  面试 C# 被人问你是如何优化你的代码的,该从哪些方面进行回答? 
  如何评价《阿里巴巴JAVA开发手册》完美版,终极版,纪念版? 

前一个讨论
爱狗人士也反对吃其他动物吗?
下一个讨论
高版本C#语法写的代码能够编译为低版本.netframework的代码吗?





© 2024-05-20 - tinynew.org. All Rights Reserved.
© 2024-05-20 - tinynew.org. 保留所有权利