Go1.25 新特性:引入 DWARF5,链接器更快,二进制文件更小了!

大家好,我是煎鱼。

Go 这一门编程语言,在推出时,相较个别语言来讲,编译后较为小的二进制文件是一个较大的卖点。

而本次在 Go1.25 新特性中,又针对缩小编译后二进制文件有了新的改善。今天分享给大家。

新提案:compile 使用 DWARF5

这个新提案《cmd/compile: consider using DWARF 5[1]》由 @Austin Clements 在 2018 年提出:

目的是期望在 Go1.25 新版本中在 Go 编译器使用 DWARF5 版本。

Go 使用 DWARF 版本情况

Go 版本

默认 DWARF 版本

说明

Go 1.0 - 1.9

DWARF v2

使用较老的 DWARF 格式,结构简单、兼容性强,但体积大、功能有限。

Go 1.10

DWARF v4 引入(部分支持)

初步支持 DWARF v4,但并非所有平台默认启用。

Go 1.11 - 1.17

DWARF v4(默认)

广泛采用 DWARF v4,改进了范围列表、位置表达式等。调试体验显著提升。

Go 1.18+

DWARF v4(压缩优化)

在 v4 基础上对 .debug_loc.debug_ranges 等采用更紧凑的编码;调试信息总体更小。

Go 1.20+

DWARF v4 + Zlib 压缩(可选)

支持压缩 DWARF 区段,缩小二进制体积,但仍为 v4。

Go 1.22+

DWARF v4 + 支持 position-independent DWARF

支持位置无关调试信息(如 DWARFv5 的一部分理念),但仍标注为 v4。

DWARF5 背景和优势

现阶段 DWARF5 还是比较新的轮子,于 2017 年发布。

在 DWARF5 的生态圈中,GNU 和 LLVM 工具链以及一些调试器都支持 DWARF5 。

GCC7.1(2017 年 5 月)和 GDB8.0(2017 年 6 月)中添加了支持大多数 Xcode 工具也支持。因此作者关注到了他。

DWARF 一共有以下几个正式版本:

原作者认为 DWARF5 与以前的 DWARF 版本相比,是具体以下几个优势的:

  • 支持位置无关的表示方式,这大大减少了目标文件中的重定位数量:

    • 从而减小了目标文件的体积并减轻了链接器的负担。

    • 在 Go 可执行文件中,503,361 个总重定位记录中有 49% 来自 DWARF。

  • 支持更为紧凑的位置与范围列表格式:即便使用 zlib 压缩,位置和范围列表区段也仅占 12MiB Go 可执行文件的 6%。

  • 为 Go 提供了官方的语言代码。

基准测试结果

根据原作者提供的基准测试结果[2],修改后(启用 DWARF 5)与修改前(原版本)的对比可以得出以下结论:

│ out.base.txt │           out.dwarf5.txt            │
                         │    sec/op    │   sec/op     vs base                │
Template                    61.56m ± 1%   61.28m ± 1%        ~ (p=0.136 n=50)
Unicode                     45.54m ± 1%   45.32m ± 1%        ~ (p=0.145 n=50)
GoTypes                     348.9m ± 0%   347.1m ± 1%   -0.52% (p=0.014 n=50)
Compiler                    47.94m ± 1%   47.04m ± 2%        ~ (p=0.061 n=50)
SSA                          2.880 ± 1%    2.863 ± 0%   -0.61% (p=0.003 n=50)
Flate                       36.76m ± 1%   36.28m ± 1%   -1.31% (p=0.001 n=50)
GoParser                    70.02m ± 1%   69.50m ± 1%   -0.75% (p=0.028 n=50)
Reflect                     178.6m ± 1%   175.6m ± 1%   -1.67% (p=0.000 n=50)
Tar                         75.51m ± 1%   74.51m ± 1%   -1.33% (p=0.001 n=50)
XML                         86.60m ± 1%   86.48m ± 1%        ~ (p=0.688 n=50)
LinkCompiler                297.5m ± 3%   295.8m ± 4%        ~ (p=1.000 n=50)
ExternalLinkCompiler       1035.6m ± 1%   887.2m ± 1%  -14.33% (p=0.000 n=50)
LinkWithoutDebugCompiler    168.0m ± 4%   166.8m ± 3%        ~ (p=0.571 n=50)
StdCmd                       14.27 ± 1%    14.16 ± 0%   -0.78% (p=0.000 n=50)
geomean                     208.8m        204.9m        -1.89%
...
  1. 外部链接器性能提升显著: ExternalLinkCompiler 测试结果显示 sec/op 链接时间降低了 -14.33%。说明 DWARF5 显著减少了外部链接器处理的压力,可能是 relocations 或 .debug_* 区段大幅简化。

  2. 用户态耗时有轻微优化:user-sec/op 平均减少约 2.67%,表明在构建、链接等过程中均有轻微的优化效果。

  3. 可执行文件体积降低:可执行文件总大小平均下降 3%,可视为 DWARF5 更紧凑的调试信息格式的直接成果。

  4. 综合无明显退化表现:没有一个 benchmark 显示性能显著下降(p<0.05 的负变化),说明 DWARF5 安全性和兼容性良好。

总结

本次 Go1.25 新特性旨意,在 Go 编译器使用 DWARF5,给 Go 应用程序的综合多个方面带来了不错的提升,提升了 Go 在编译和体积等原本强项上的更进一步提高。

这可能也是促进一些同学升级的契机之一。目前该提案已经合并到 master 分支并关闭该提案。

如无意外,我们将会在下一个新版本就可以享受到了。

参考资料

[1] 

cmd/compile: consider using DWARF 5: https://github.com/golang/go/issues/26379

[2] 

基准测试结果: https://github.com/golang/go/issues/26379#issuecomment-2576441539

关注和加煎鱼微信,

一手消息和知识,拉你进技术交流群👇

你好,我是煎鱼,出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉,点击蓝字查看我的出书之路

日常分享高质量文章,输出 Go 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!

原创不易 点赞支持

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值