百科问答小站 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 网友的相关建议: 
      

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




  

相关话题

  你见过哪些令你瞠目结舌的C#代码? 
  你什么时候对 Java 感到绝望? 
  为什么很多新型编程语言都抛弃了 C 语言风格的 for 语句? 
  为什么没有新的支持底层达到类似C++这种程度,而易用性达到C#的语言出现? 
  老师说linq语句过时了,是真的吗? 
  点语法最早是在哪个编程语言中出现的? 
  为什么这个程序电脑运行的结果和手机运行的不一样?数值小的时候一样? 
  c#中,is或者as做类型转换是否影响效率,有必要缓存吗? 
  计算机专业必读哪些经典书籍? 
  C语言里a>b?a<c?a:b:c;这个怎么该判断? 

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





© 2024-11-21 - tinynew.org. All Rights Reserved.
© 2024-11-21 - tinynew.org. 保留所有权利