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

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




  

相关话题

  如今 Windows 软件开发究竟该用什么库,C#、Qt,还是其他? 
  如何看待 2019 年 JAVA 开发就业减少现象? 
  C#能分配内存连续的引用类型数组吗? 
  为什么 Java 只有值传递,但 C# 既有值传递,又有引用传递,这种语言设计有哪些好处? 
  如何评价.NET Core 1.0称使用.NET Core运行速度是Node.js的八倍,Go的三倍? 
  把 string 当 enum 用,有性能损失吗? 
  C++中,自定义函数写在main之前更好,还是之后更好? 
  C#中关于List<T>和HashSet<T>应用的效率问题? 
  面向对象编程中, 接口既然不能直接描述方法, 要他有何用? 
  现在 Qt 好找工作吗? 

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





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