大家好,我是煎鱼。
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 基础上对 |
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%
...
外部链接器性能提升显著:
ExternalLinkCompiler
测试结果显示sec/op
链接时间降低了-14.33%
。说明 DWARF5 显著减少了外部链接器处理的压力,可能是relocations
或.debug_*
区段大幅简化。用户态耗时有轻微优化:
user-sec/op
平均减少约 2.67%,表明在构建、链接等过程中均有轻微的优化效果。可执行文件体积降低:可执行文件总大小平均下降 3%,可视为 DWARF5 更紧凑的调试信息格式的直接成果。
综合无明显退化表现:没有一个 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 面试、工作经验、架构设计,加微信拉读者交流群,和大家交流!
原创不易 点赞支持