Go1.17新特性 ,给我们带来了10%的性能提升
在 Go1.17 发布后,我们惊喜的发现 Go 语言他又又又优化了,编译器改进后产生了约 5% 的性能提升,也没有什么破坏性修改,保证了向前兼容。
他做了些什么呢,好像没怎么看到有人提起。为此今天煎鱼带大家来解读两新提案:
《Proposal: Register-based Go calling convention[1]》
《Proposal: Create an undefined internal calling convention[2]》
本文会基于提案讲解和拆解,毕竟分享新知识肯定要从官方资料作为事实基准出发。
背景
在以往的 Go 版本中,Go 的调用约定简单且几乎跨平台通用,其原因在于选用了基于 Plan9 ABI 的堆栈调用约定,也就是函数的参数和返回值都是通过堆栈上来进行传递。
这里我们一共提到了 Plan9 和 ABI,这是两个很关键的理念:
Plan9:Go 语言所使用的汇编器,Rob Pike 是贝尔实验室的猛人。
ABI:Application Binary Interface(应用程序二进制接口),ABI 包含了应用程序在操作系统下运行时必须遵守的编程约定(例如:二进制接口)。
该方案的优缺点如下:
优点:实现简单,简化了实现成本。
缺点:性能方面付出了不少的代价。
按我理解,在 Go 语言初创时期,采取先简单实现,跑起来再说。也合理,性能倒不是一个 TOP1 需求。
Go1.17 优化
什么是调用惯例
在新版本的优化中,提到了调用惯例(calling convention)的概念,指的是调用方和被调用方对函数调用的共识约定。
这些共识包含:函数的参数、返回值、参数传递顺序、传递方式等。
双方都必须遵循这个约定时,程序的函数才能正常的运行起来。如果不遵循,那么该函数是没法运行起来的。
优化是什么
在 Go1.17 起,正式开始基于 Go 内部 ABI 规范(在 Go 函数之间使用),并且从原有的基于堆栈的函数参数和结果传递的方式改为基于寄存器的函数参数和结果传递。
在性能上,现在直接存储和计算都在寄存器上,和以前基于堆栈存储,再计算相比,现在这种模式势必是性能更优的。
本次修改涉及到的项非常多,该优化是持续的,原本预计是 Go1.16 实现,不过拖到了 Go1.17。
目前实现了 amd64 和 arm64 架构的支持。还有不少的更多的支持会持续在 Go1.18 中完成,具体进度可见 issues #40724[3]。
性能如何
在 Go1.17 Release Notes[4] 中明确指出,用一组有代表性的 Go 包和程序的基准测试。
官方数据显示:
Go 程序的运行性能提高了约 5%。
Go 所编译出的二进制大小的减少约 2%。
在民间数据来看,在 twitter[5] 看到 @Achille 表示从 Go1.15.7 升级到 Go1.17 后显示。在一个大规模的数据处理系统上进行的 Go1.17 升级产生了惊人的效果,我们来看看他的真实数据。
CPU、Malloc 调用时间减少了约15%:
图来自 @Achille
图来自 @Achille
RSS 大小更接近于堆的大小:
图来自 @Achille
内存方面从原本的 1.6GB 降至 1GB。
结合官方和民间数据来看,优化效果是明确且有效的。有兴趣的小伙伴也可以自己测一测。
不过需要注意,@Achille 的数据是包含 Go1.16 和 Go1.17 的优化的,没法直接对比,但可以参考。
总结
在 Go1.17 这一个新版本中,只需要简单的升一升 Go 版本,我们就能得到一定的性能优化,这是非常不错的。
不过这一改动,Go 的汇编又变了,怕不是市面上很多文章或书的部分内容又失效了。
从以往的基于堆栈的函数参数和结果传递的方式改为 Go1.17~Go1.18 基于寄存器的函数参数和结果传递,Go 语言正在一步步走的更好!
你觉得呢?
关注煎鱼,吸取他的知识
Go1.17新特性 ,给我们带来了10%的性能提升相关推荐
- 2022年最细Java 17新特性,是真的猛,被征服了!
SpringBoot 正式支持Java 17,Kafka3.0弃用Java8 Spring Boot 2.5.5是Spring Boot 第一个支持Java 17的版本.现在你已经可以从Spring ...
- Java 17新特性,快到起飞?惊呆了!
都说Java 8 是YYDS,那你注意到 Java 17 也是长期支持版本吗?目前按计划 JDK 19 将于今年 9 月发布 SpringBoot 正式支持Java 17,Kafka3.0弃用Java ...
- Go1.18 新特性:多模块(Multi-Module)工作区模式
文章目录 背景 举例:未发布的 module Go1.18 新特性:多模块(Multi-Module)工作区模式 Go1.18 工作区模式 初始化一个新的工作区 go work use 添加新的模块到 ...
- k8s v1.17 新特性预告: 拓扑感知服务路由
大家好,我是 roc,来自腾讯云容器服务(TKE)团队,今天给大家介绍下我参与开发的一个 k8s v1.17 新特性: 拓扑感知服务路由. 01 名词解释 拓扑域: 表示在集群中的某一类 " ...
- go每日新闻(2021-02-02)——Go1.16 新特性:一文快速上手 Go embed
每日一谚:The Go analogue: goroutines connected by channels just like unix pipes style. go中文网每日资讯–2021-02 ...
- 盘点 Oracle 11g 中新特性带来的10大性能影响
盘点 Oracle 11g 中新特性带来的10大性能影响 原创 2017-08-02 盖国强 数据和云 Oracle的任何一个新版本,总是会带来大量引人瞩目的新特性,但是往往在这些新特性引入之初,首先 ...
- C++11/14/17 新特性总结
C++11/14/17 新特性总结 initializer_list std::vector<int> vctInts({92, 12, 39, 46, 92, 84, -1, 0, -2 ...
- Go1.18 新特性:高效复制,strings, bytes 库新增 Clone 功能
大家好,期盼已久的 Go1.18 上周已经发布,今天给大家带来一个 1.18 版本新特性中的优化相关的内容,是与 strings 和 bytes 标准库有关. 背景 想要更快捷复制 在日常编程中,字节 ...
- Java 17新特性,快到起飞?
都说Java 8 是YYDS,那你注意到 Java 17 也是长期支持版本吗?目前按计划 JDK 19 将于今年 9 月发布 SpringBoot 正式支持Java 17,Kafka3.0弃用Java ...
最新文章
- PL/SQL三种集合类型的比较
- 干货丨一文看懂人工智能、机器学习和深度学习的区别与联系
- 美国芯片简史:军方大力扶持下的产物 但一度被日 韩超越
- bzoj 2179 FFT快速傅立叶
- Spring xml 配置使用外部config 文件
- 编写可变参数函数 c语言,C语言中编写可变参数函数
- noip2004普及组第2题 花生采摘
- 关于PHP的OpenSSL的加密问题
- Win10安装配置CLion+MinGW
- Javascript实现鼠标框选元素后拖拽被框选的元素
- 20172315 2017-2018-2 《程序设计与数据结构》实验三报告
- matlab热应力计算,Matlab在齿轮应力计算中的应用
- 【原创】技术员 Win10 PE 网络版启动工具 V6.2 兼容UEFI双启动
- FW: Why PUT and DELETE?铪铪
- ps插件套装imagenomic磨皮滤镜安装教程
- Processing摸索前行(8)-弹珠游戏
- yarn打包报错:error during build: Error: Assigning to rvalue (Note that you need plugins to import files
- Groovy语言 Grails框架入门
- Digispark ATTINY85 Arduino IDE 开发
- 李嘉诚:无霸气才能成霸业
热门文章
- maven 指定jdk版本打包
- php导出数据到excel,防止身份证等数字字符格式变成科学计数的方法
- UML学习笔记(六)【状态图】
- 结对编程:黄金分割游戏
- swift学习笔记之一——初见swift
- 解决/usr/bin/ld: cannot find -lxxx
- Squid 2.6 Configuration Manual - Log File Path Names and Cache Directories
- 20172318 2018-2019-1 《程序设计与数据结构》第9周学习总结
- Linux系统CentOS 7配置Spring Boot运行环境
- 勒索病毒入侵中国, Splunk建议网络立即进行区分和隔离设置