.NET Core中的去虚
极客时间编辑部
讲述:丁婵大小:1.18M时长:02:34
在.NET 最初被设计出来时,方法在默认情况下必须是非虚方法,原因之一是,非虚方法通常比虚方法快很多。
除了虚函数表查询本身的成本之外,虚函数通常还无法内联。由于.NET 的发展趋势是倾向于使用大量的小方法,所以非内联方法的函数调用开销,最终会超过方法本身的开销。
在过去的几年中,我们习惯的 C# 一直在变化。以前,大接口并不常见,但现在,可以完全匹配所有类的“影子接口”都非常常见了。而随着 DI 框架性能的提升,在项目中见到面向所有非 DTO 类的影子接口已经很平常了。
方法去虚有多种方式,本质上讲,就是在特定的情况下把它们视为非虚方法。Java HotSpot 就以具备这项特性而闻名。在 Java 中,所有方法在默认情况下都是虚方法,因此,在 Java 的历史中,解决这种性能问题的需求出现得早很多。
在今年三月份,.NET Core 悄悄地对“去虚(Devirtualization)”发起了挑战。简单去虚特性处理了三种基本的场景:
在 sealed 类上调用虚方法;
在 sealed 方法上调用虚方法;
在明确知道类型的情况下调用虚方法(例如,紧挨着构造函数)。
接口去虚也有一些基础的支持,但有限制。例如,如果方法是 final 的,而类不明确或者不是 final 的,则不允许接口去虚,因为派生类在实现接口时还可以重写 final 方法。
需要注意的是,仅仅将类标记为“sealed”是不足以从去虚接口受益的。如果开发者正在使用 DI 框架时隐藏运行时使用了哪个具体类,那么 JIT 编译器可能无法确定使用了什么类型。
.NET Core 2.0 提供了上述特性,但还有许多工作要做,如尽可能地减少虚调用和装箱,毕竟众所周知,在涉及接口调用时,结构很糟糕,因为它们不仅是虚的,还需要对值进行装箱。
还有 JIT 本身的类型跟踪改进。显然,在许多情况下,JIT 在一个地方知道具体的类型,但无法将信息传递下去,因此,JIT 不得不采用更通用的机器代码。
同时,试探性去虚也在考虑范围。根据概述,该特性不会和 Java 里的一样。更准确地说,它会根据 JIT 过程中已知的覆写清单做决定。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
该免费文章来自《极客视点》,如需阅读全部文章,
请先领取课程
请先领取课程
免费领取
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
精选留言
由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论