写点什么

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

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

关注

评论

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

一文读懂当今AI圈大热的“MLOps”

澳鹏Appen

人工智能 机器学习 大数据 数据标注 运维开发

换掉bpmn-js,让前端更熟悉工作流业务

相续心

前端 流程图 workflow

软件测试需要学习什么?好学吗?需要学多久?到底是报班好还是自学好?

伤心的辣条

程序员 程序人生 软件测试 自动化测试 Python自动化

数据库每日一题---第11天:合作过至少三次的演员和导演

知心宝贝

数据库 前端 后端 6月月更

vue监听器

小恺

6月月更

实时数仓实战

鲸品堂

数据 实时数仓

投稿开奖丨云服务器ECS征文活动(3月)大奖公布

阿里云弹性计算

DNS 云服务器 ECS DoH

黄硕:百度飞桨文心大模型在语音文本审核中的应用

声网

RTC Dev Meetup 生态专栏 语音处理

线程的创建方法

卢卡多多

线程池 线程安全 6月月更

浅谈隐私计算与数据安全

I

学习笔记 数据安全 隐私计算 可信安全计算

【愚公系列】2022年06月 通用职责分配原则(一)-信息专家原则

愚公搬代码

6月月更

静态链接,静态分派,动态链接

北洋

android 6月月更

让你驱动力开机工作了,不是在待机状态。

叶小鍵

快速实现微信登录第三方小程序快捷方式

Geek_99967b

小程序 小程序转app

剑指 Offer 58 - II. 左旋转字符串

未见花闻

6月月更

Notebook在复现数据科学研究成果中的丝滑使用

Baihai IDP

AI notebook 数据科学 科研成果

看完就会,从抓包到接口测试的全过程解析

伤心的辣条

程序员 自动化测试 接口测试 测试开发 Python自动化

如何方便的将小程序转换成APP

Geek_99967b

小程序 小程序容器

SQL优化

工程师日月

6月月更

华为云Stack首席架构师:打造“称手”的数字化工具,答好政企IT数字化转型这道必选题

华为云开发者联盟

云计算 数字化转型 多云管理 华为云Stack

用FinClip实现App小程序微信授权登录详解

Geek_99967b

小程序 小程序容器

模块四(千万级学生管理系统的考试试卷存储方案)

Geek_701557

比Postman更适合国人的接口调试工具

伤心的辣条

程序员 自动化测试 接口测试 Python自动化 程序员程序人生

在万家灯火阑珊处,重新认识平板电脑

脑极体

Lazada的算法本土化实践:让东南亚没有难投放的广告

科技新知

Vue3 Composition API如何替换Vue Mixins

源字节1号

前端开发 小程序开发

flutter系列之:flutter中常用的ListView layout详解

程序那些事

flutter 程序那些事 6月月更

想秀你就秀!环信MVP招募计划正式启动,诚邀您加入!

环信

IT 即时通讯 IM 技术分享

ConcurrentHashMap 源码分析-扩容

zarmnosaj

6月月更

gRPC C++开发环境搭建

赖猫

c c++ gRPC

架构实战营模块 8 作业

热猫

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