写点什么

.NET Core 中的去虚

  • 2017-12-24
  • 本文字数:1232 字

    阅读完需:约 4 分钟

在.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

2017-12-24 18:002432
用户头像

发布了 1008 篇内容, 共 446.0 次阅读, 收获喜欢 346 次。

关注

评论

发布
暂无评论
发现更多内容

手把手教你免费获取正版 Jetbrains 全家桶 License

郭旭东

ide JetBrains

阿里三面惨遭被虐,spring,jvm,mybatis,并发编程等一窍不通

Java架构之路

Java 程序员 架构 面试 编程语言

互联网新规鼓励保险与大数据、区块链等新技术融合!业内呼吁配套产品管理制度尽快出炉

CECBC

互联网金融

快来!开源一份阿里微服务指导手册:springBoot+springCloud+MQ

小Q

学习 面试 微服务 MQ SpringCloud

海淀区政府携手百度,打造数字政务时代新门户

DT极客

SpringBoot魔法堂:应用热部署实践与原理浅析

设计原则 框架 spring Boot Starter

有了Git这个功能,再也不需要依赖IDE了!

编程 架构

盘点 2020 | 坚持写技术博客一年能有多少收获!

小傅哥

Java 小傅哥 技术人 盘点2020

如何在软件发布计划中自动化语义化版本与变更日志

华为云开发者联盟

自动化 工具 发布

一个改变世界的“箱子”

阿里巴巴云原生

Docker 阿里云 容器 云原生 k8s

终于学完了阿里云大数据架构师推荐的Flink入门与实战PDF

小Q

大数据 flink 学习 编程 面试

聚焦LS-MIMO的四大层面,浅谈5G关键技术

华为云开发者联盟

华为 5G 华为云

基于LiteOS Studio零成本学习LiteOS物联网操作系统

华为云开发者联盟

操作系统 物联网 华为云

BAT等大厂面试复习资料文档整理:ActiveMQ+redis+Spring+高并发多线程+JVM

Java架构之路

Java 程序员 架构 面试 编程语言

BATJ面试常被问到的100+题:Spring+微服务+SpringMVC+MyBatis

Java架构之路

Java 程序员 架构 面试 编程语言

工作日志:一文总结HBase从搭建到实操,大家一起进步

小Q

大数据 学习 编程 面试 HBase

我叫你不要重试,你非得重试。这下玩坏了吧?

比伯

Java 编程 架构 面试 程序人生

即构SDK12月迭代:新增多项质量回调,互动白板、云录制SDK同步更新

ZEGO即构

LeetCode题解:429. N叉树的层序遍历,BFS,JavaScript,详细注释

Lee Chen

算法 大前端 LeetCode

没弄懂这些Java基础,简历上千万别写熟悉:异常+反射+注解+泛型

小Q

Java 学习 编程 面试 基础

XMEX交易所系统软件开发|XMEX交易所APP开发

系统开发

终于有人通过笔记+脑图+视频的模式把Spring源码讲明白了

Java架构追梦

Java 学习 架构 面试 spring源码

探营苏州数字人民币试点

CECBC

数字人民币

第三代人工智能基础设施背后,是一次技术应用的常识普及运动

脑极体

Athena雅典娜交易所系统开发|Athena雅典娜交易所软件APP开发

系统开发

你只修改了2行代码,为什么需要两天时间?

Java架构师迁哥

破51项国际榜单纪录!解读华为云擎天架构调度求解引擎

华为云开发者联盟

华为 架构 华为云

赶紧看!阿里架构师必备“绝杀版”Tomact架构笔记堪称绝技

比伯

Java tomcat 编程 架构 程序人生

社区团购大战升级:零售行业再次面临挑战

石头IT视角

网络入门模拟器:Cisco Packet Tracer 实验教程

C语言服务器编程必备常识

MySQL从删库到跑路

c

.NET Core中的去虚_.NET_Jonathan Allen_InfoQ精选文章