写点什么

.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:002457
用户头像

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

关注

评论

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

产品迭代为什么越来越慢?

Feedalyze

效率工具 产品经理 产品运营 产品迭代 用户需求

Java 中堆内存和栈内存上的数据分布和特点

量贩潮汐·WholesaleTide

Java JVM

2025深圳高交会·第二十七届中国国际高新技术成果交易会

AIOTE智博会

高交会 人工智能展 深圳高交会

成功案例丨GEZE与Altair合作推动智能建筑系统开发

Altair RapidMiner

制造业 数字孪生 仿真 CAE 工业仿真

淘宝商品详情API接口解析与 Python 实战指南

tbapi

淘宝API接口 淘宝商品详情接口 淘宝数据采集 淘宝商品详情数据采集

ListenHub :短播客内容生成和消费 Agent;Ollama 新引擎支持多模态推理模型,将支持语音生成丨日报

RTE开发者社区

圆明园十二生肖兽首铜像终于“回国”?百度百科推出数字文物守护计划,让流失文物回家

科技大数据

1688图片搜索API接口攻略

tbapi

1688图片搜索接口 1688拍立淘接口 1688图片api

YashanDB|YAS-02507:执行增量备份失败?缺少基础备份

数据库砖家

数据库

昇腾AI云服务,中国AI的翼翼长城

脑极体

云计算

数据分析与AI丨Graph+LLM 如何重塑传统 BI 的未来

Altair RapidMiner

人工智能 AI 数据分析 知识图谱 GraphStudio

Last Call丨精彩嘉宾阵容,完整日程揭秘!2025 Altair 区域技术交流会华北站

Altair RapidMiner

人工智能 AI 汽车 数字孪生 CAE

同样的数据,更强的效果:如何让模型学会‘互补思维’?

量贩潮汐·WholesaleTide

人工智能 机器学习

朱雀二号改进型火箭成功发射!国产时序数据库 IoTDB 全程护航火箭试验、发射及北邮双星数据管理

Apache IoTDB

YashanDB 登录提示账户被锁?快速解锁 sys 用户的方法

数据库砖家

数据库

YashanDB|YAS-02287:审计策略无法删除?因为还在启用中

数据库砖家

数据库

小度AI助手携手博西家电达,共筑智能家居新场景

科技大数据

Web前端入门:JavaScript 3 种书写位置及 script 标签的正确存放位置

不在线第一只蜗牛

Java 前端 Web

整合安全能力:观测云进一步强化数据价值

观测云

安全

英特尔发布专业级GPU,专为AI推理和专业工作站设计

E科讯

YashanDB|报错 YAS-00402:failed to connect socket?可能是监听地址设置问题

数据库砖家

数据库

YashanDB|YAS-02605:不是 Master 节点无法执行恢复?共享集群下的角色限制

数据库砖家

数据库

WPS深度适配鸿蒙电脑折叠形态,打造全新多端智能办公体验

最新动态

YashanDB|YAS-02547:归档恢复报错“日志存在间断”?归档序号不连续所致

数据库砖家

数据库

打印高质量日志的10条军规

电子尖叫食人鱼

git

学啥才能接单?分享一下我目前使用的技术栈

程序员郭顺发

yashandb:自关联外键插入数据时报错

数据库砖家

数据库

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