【译文】Go语言性能从 1.0 版到 1.22 版
内容提要
本文重新运行了GoAWK解释器在Go 1.0至1.22版本上的基准测试,并添加了缺失的版本和新版本。比较了GoAWK在不同版本编译时的性能,包括字符串处理和数字计算。结果显示,Go 1.3、1.5、1.7和1.12版本有最大的改进。在Go 1.2中,数词的速度出现了奇怪的提升,然后又下降。通过剖析找出了1.2版本异常的原因。在使用Go 1.22的情况下,PGO只提高了几个百分点的性能。总的来说,countwords现在的速度是Go 1.0的8倍,sumloop是它的24倍。
延伸解读
性能提升的关键版本
文章指出,Go 1.3、1.5、1.7 和 1.12 是性能改进最大的版本。这些改进主要来自编译器优化、运行时和垃圾回收器的增强。在此之后,性能提升变得更为渐进,因为容易实现的优化已经完成。这提醒开发者,升级到这些关键版本可能带来显著收益,而后续版本则更多是细微改进。
Go 1.2 的性能异常与修复
在 Go 1.2 中,sumloop 基准测试出现了奇怪的性能下降,从 1.1 的 7.5 秒变为 25.5 秒,然后在 1.3 中恢复到 2.8 秒。剖析显示,运行时堆栈操作(如 newstack、oldstack)占用了大量时间。原因是 goroutine 堆栈从分段模型改为连续模型时引入了“热分割”问题,该问题在 1.3 中得到解决。这说明了运行时内部变化对性能的潜在影响。
PGO 的实际效果与二进制大小
在 Go 1.22 中,使用配置文件引导优化(PGO)对性能提升有限:countwords 仅提高约 2%,sumloop 约 7%。同时,启用 PGO 后二进制文件大小仅增加 5%。作者认为这通常是值得的。这表明 PGO 在当前阶段带来的收益较小,但代价也不高,开发者可以根据需求权衡是否启用。
长期性能改进的幅度
从 Go 1.0 到 1.22,countwords 基准测试的速度提升了 8 倍,sumloop 提升了 24 倍。这体现了 Go 团队在编译器、运行时和标准库上的持续优化。对于计算密集型任务,性能提升尤为明显。开发者可以预期,长期升级 Go 版本会带来可观的性能收益,尤其是对于循环和数值计算场景。
Q&A
Go语言的性能在不同版本之间有何变化?
Go 1.3、1.5、1.7和1.12版本的性能改进最大,countwords的速度是Go 1.0的8倍,sumloop是24倍。
Go 1.2版本的性能异常是如何产生的?
Go 1.2版本的性能异常是由于堆栈热分割问题造成的,运行时堆栈操作占用了较大比例的运行时间。
PGO在Go 1.22版本中的性能提升效果如何?
在Go 1.22中,PGO仅提高了几个百分点的性能,对countwords约为2%,对sumloop约为7%。
GoAWK的基准测试是如何进行的?
基准测试使用了两个AWK程序,分别测试字符串处理和数字计算的性能。
Go语言在性能优化方面做了哪些改进?
Go团队和外部贡献者改进了编译器,优化了运行时、垃圾回收器和标准库。
Go 1.0和1.22版本的二进制文件大小变化如何?
多年来,二进制文件的大小保持稳定,1.2版本出现较大增长,启用PGO后仅增大5%。