Go 性能 13 年大复盘:26 个版本全部实测,Go 1.27 比 1.23 快 11.5%

Go 性能 13 年大复盘:26 个版本全部实测,Go 1.27 比 1.23 快 11.5%

💡 原文中文,约6500字,阅读约需16分钟。
📝

内容提要

Praneos Labs 在相同硬件与源码下,对 Go 1.2 至 1.27 共 26 个版本进行无缓存压测。结果显示,Go 1.27 比 1.23 快 11.5%,比 1.2 快约 41%。性能提升主要来自 Go 1.5–1.7 的编译器重构和 1.24–1.27 的 runtime 优化,中间七年吞吐量基本平稳。map 密集型和频繁重分配的程序提速明显,纯数值计算自 1.7 后几乎无变化。Go 与 C 的差距多源于手写 SIMD 指令,在标量对比下差距已缩小至 0%–30%。

🔎

延伸解读

性能提升并非均匀分布

文章显示,Go 1.27 相比 1.23 的整体提速 11.5% 是几何平均值,但具体到不同程序差异巨大。map 密集型程序如 k-nucleotide 耗时下降 57.5%,而纯数值计算如 n-body、mandelbrot 等几乎无变化。这意味着升级收益高度依赖代码特征,开发者需根据自身业务类型评估预期。

七年平稳期背后的取舍

从 Go 1.8 到 1.23 的七年里,吞吐量仅变化约 3%,但这并非停滞。文章指出,这段时间 runtime 团队主要精力用于降低 GC 停顿,收益体现在延迟而非吞吐量。因此,若应用对延迟敏感,这些版本的升级价值可能远高于吞吐量基准所反映的水平。

内存布局优化可能比升级更有效

文章中的 binary-trees 实验表明,通过预分配内存池和用下标替代指针,程序耗时从 11.28 秒降至 1.09 秒,提速约 10 倍,远超版本升级带来的收益。这提示开发者,对于重分配型程序,优化内存布局可能比单纯升级 Go 版本更值得投入。

与 C 的差距需理性看待

文章分析指出,Go 在基准测试中落后 C 数倍,主要源于 C 程序使用了手写 SIMD 指令。在纯标量对比下,差距缩小至 0%~30%,个别任务甚至反超。因此,看到“Go 比 C 慢几倍”的说法时,应关注对比条件是否包含 SIMD 等平台特定优化。

❓

Q&A

Go 1.27 比 Go 1.23 和 Go 1.2 分别快多少?

根据 Praneos Labs 的测试,Go 1.27 比 Go 1.23 整体快 11.5%,比 13 年前的 Go 1.2 快约 41%。

Go 性能提升主要发生在哪些版本阶段?

性能提升主要集中在两个阶段:Go 1.5 到 1.7 的编译器重构(自举和 SSA 后端),以及 Go 1.24 到 1.27 的 runtime 优化。中间 Go 1.8 到 1.23 的七年吞吐量基本平稳。

哪些类型的程序从 Go 新版本中受益最大?

高频使用 map、重内存分配、依赖 GC 的业务型代码提升惊人。例如,map 密集型程序因 Swiss Table 优化耗时减少 57.5%,binary-trees 因 GC 和内存分配器优化减少 30.7%。而纯数值计算循环自 Go 1.7 后几乎无变化。

Go 与 C 的性能差距主要来自哪里?

Go 与 C 的差距大部分源自 C 程序使用的手写 SIMD 向量化指令。在纯标量代码对比下,Go 与 C 的差距已缩小至 0%~30%,个别任务甚至反超。

升级 Go 版本能省电吗?

根据能耗模型估算,Go 1.27 比 Go 1.23 省电 11.5%,比 Go 1.8 省电 14%。程序的绝对运行时长对服务器总能耗的影响远高于占用了多少个核心。

对于重分配型程序,有什么优化建议?

对于重分配型程序,优先改内存布局。例如,使用预分配 slice 和 int32 下标代替指针,避免 GC 扫描,可带来约 10 倍的提速,远大于升级 Go 版本本身的收益。

🏷️

标签

➡️

继续阅读