当前位置: 首页 > news >正文

.NET Core中的去虚

在.NET最初被设计出来时,方法在默认情况下必须是非虚方法。这有几个原因,其中一个是,非虚方法通常比虚方法快很多。除了虚函数表查询本身的成本之外,虚函数通常还无法内联。由于.NET的发展趋势是倾向于使用大量的小方法,所以非内联方法的函数调用开销最终会超过方法本身的开销。我们在文章“关于C#的抽象与For-Each性能”中介绍了这种内联的部分效果。

\\

在过去的几年中,我们习惯的C#一直在变化。以前,大接口并不常见,但现在,可以完全匹配所有类的“影子接口”都非常常见了。这始于WCF,它鼓励这种做法,虽然不是必须的。随着DI框架性能的提升,在项目中见到面向所有非DTO类的影子接口已经很平常了。

\\

方法去虚有多种方式,本质上讲,就是在特定的情况下把它们视为非虚方法。Java HotSpot就以具备这项特性而闻名。在Java中,所有方法在默认情况下都是虚方法,因此,在Java的历史中,解决这种性能问题的需求出现得早很多。

\\

在今年三月份,.NET Core悄悄地对“去虚(Devirtualization)”发起了挑战。简单去虚特性处理了三种基本的场景:

\\
  • 在sealed类上调用虚方法; \\
  • 在sealed方法上调用虚方法; \\
  • 在明确知道类型的情况下调用虚方法(例如,紧挨着构造函数)。 \

接口去虚也有一些基础的支持,但有限制。例如:

\\
\

如果方法是final的,而类不明确或者不是final的,则不允许接口去虚,因为派生类在实现接口时还可以重写final方法。

\
\\

需要注意的是,仅仅将类标记为“sealed”是不足以从去虚接口受益的。如果你正在使用DI框架隐藏运行时使用了哪个具体类,那么JIT编译器可能无法确定使用了什么类型。

\\

这在Java中之所以不是问题,是因为Java去虚技术的工作原理完全不同。它是根据运行时指标试探性地去虚接口调用,对最常调用的方法重新即时编译。其中还包含了专门的防卫语句,以防具体的类型修改和去虚需要解除。

\\

展望

\\

.NET Core 2.0提供了上述特性,但还有许多工作要做。下面是去虚路线图上的部分重点工作。

\\

众所周知,在涉及接口调用时,结构很糟糕,因为它们不仅是虚的,而且还需要对值进行装箱。因此,有几项工作是为了尽可能地减少虚调用和装箱。其中一个重要的部分是一类结构,这是一个高级JIT概念,超出了本报道的范围。

\\

JIT本身的类型跟踪改进。显然,在许多情况下,JIT在一个地方知道具体的类型,但无法将信息传递下去,因此,JIT不得不采用更通用的机器代码。

\\

试探性去虚也在考虑范围。根据概述,该特性不会和Java里的一样。更准确地说,它会根据JIT过程中已知的覆写清单做决定。(据推测,这会用在接口只有单个类实现的情况下,这在上文提到的DI场景下经常发生。)

\\

其中有一种特殊情况,就是EqualityComparer.Default防卫去虚。由于在绝大多数情况下,IEqualityComparer调用都会指向默认实现(视情况不同,要么是IEquatable,要么是Object.Equals),所以他们觉得,如果不减慢使用非默认IEqualityComparer的情况,那么提升使用默认实现场景的执行速度是值得的。

\\

查看英文原文:Devirtualization in .NET Core

相关文章:

  • php获取数组长度的方法
  • 恢复误删除的ESXi服务器存储VMFS卷
  • .NET 反射的使用
  • vim/vi卡死
  • ECSHOP修改后台地址
  • WebCast听课录(5)
  • 数字音乐维权联盟首次出招 QQ音乐起诉酷我索赔千万
  • Pure-ftpd无法连接到服务器 425错误
  • 华为交换机ntp设置
  • 同源策略
  • 硬盘驱动器
  • Powershell 修改AD用户属性
  • Unicode和多字节的相互转换
  • 基于C++任意点数的FFT/IFFT(时域和频域)实现
  • 第 19 章 Class
  • Akka系列(七):Actor持久化之Akka persistence
  • Android 初级面试者拾遗(前台界面篇)之 Activity 和 Fragment
  • Angular6错误 Service: No provider for Renderer2
  • CAP 一致性协议及应用解析
  • Computed property XXX was assigned to but it has no setter
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • java概述
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • XML已死 ?
  • 基于Vue2全家桶的移动端AppDEMO实现
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 前端临床手札——文件上传
  • 前嗅ForeSpider教程:创建模板
  • 三分钟教你同步 Visual Studio Code 设置
  • 使用common-codec进行md5加密
  • 使用Gradle第一次构建Java程序
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 我看到的前端
  • 一些css基础学习笔记
  • 因为阿里,他们成了“杭漂”
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • #include
  • #考研#计算机文化知识1(局域网及网络互联)
  • $().each和$.each的区别
  • ${ }的特别功能
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (pt可视化)利用torch的make_grid进行张量可视化
  • (zt)最盛行的警世狂言(爆笑)
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (多级缓存)多级缓存
  • (九)信息融合方式简介
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (免费领源码)python+django+mysql线上兼职平台系统83320-计算机毕业设计项目选题推荐
  • (十八)三元表达式和列表解析
  • (小白学Java)Java简介和基本配置
  • (已更新)关于Visual Studio 2019安装时VS installer无法下载文件,进度条为0,显示网络有问题的解决办法
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)用.Net的File控件上传文件的解决方案
  • *2 echo、printf、mkdir命令的应用
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全