百科问答小站 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++中,含有函数声明的头文件应该被包含在定义函数的源文件中? 
  如果你是一个C++面试官,你会问哪些问题? 
  现在 c++中 long 整数类型还有使用的意义吗? 
  C#相对路径 连接Access数据库怎么写?? 
  C语言指针难吗?如何看待数学大v认为指针比范畴论还难? 
  C#异步方法返回Task的意义是什么?完整的TAP代码是什么结构? 
  对容器类做改变的设计是否存在天生的错误? 
  开源社区很多开源框架都有Rails的影子,为什么不用Rails呢? 
  优化代码中大量的if/else,你有什么方案? 
  C# 和 Java 哪个更像 C++? 

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





© 2024-12-26 - tinynew.org. All Rights Reserved.
© 2024-12-26 - tinynew.org. 保留所有权利