编程与软件工程lifthrasiir.github.io
为什么 Rust 可执行文件这么大?
Why is a Rust executable large?
2016 — 2019,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这篇文章以 Rust 的 Hello World 等可执行文件为例,拆解它为什么比同等 C 程序大:静态链接的标准库/运行时、调试信息,以及当时默认使用的 jemalloc 等都会计入体积。作者还演示了 strip、动态链接和直接调用系统接口等减小二进制的方法,并比较不同构建选项的取舍。
为什么经久不衰:因为它把“二进制为什么大”还原为链接方式、调试信息和运行时的具体取舍,给出可操作的优化路径,所以多年后仍是理解 Rust 构建体积的经典入口。
HN 评论精选
区分调试信息与符号表,建议用 strip --strip-debug,并配合 -ffunction-sections/-fdata-sections 使用 --gc-sections。
我一直在做一个工具,想回答更一般的问题:为什么我的二进制文件(C、C++、Rust 等写的)这么大?我们用 CPU profiler 解释程序为什么慢,我的工具则像 size profiler:程序为什么大?对文章有几点直接评论:不建议完全 strip,改用 strip --strip-debug(或者干脆不用 -g 编译);调试信息和符号表是两回事,调试信息大得多(4 倍以上)且远非必需,去掉调试信息但保留符号表仍能获得 backtrace。另外,我不认为 -Wl,--gc-sections 有效,除非同时用 -ffunction-sections 和/或 -fdata-sections 编译,而文中的 C/C++ 示例没有这样做。现在如果在乎 C/C++ 二进制大小,大概应该加上这些选项,可惜它们不是默认。
haberman查看英文原文
I've been playing around with a tool to answer the more generic question: why is my binary (written in C, C++, Rust, etc) so large? We use CPU profilers to tell us why our programs are slow. My tool is intended to be a size profiler: why is my program big? It turns out there are some really interesting analyses and visualizations you can perform to answer this question. A few direct comments on the article: - I do not recommend stripping your binaries completely! Use "strip --strip-debug" instead (or just don't compile with -g). You should realize that debug information and the symbol table are two separate things. The debug information is much larger (4x or more) and much less essential. If you strip debug information but keep the symbol table, you can still get backtraces. - I don't believe -Wl,--gc-sections has any effect unless you also compile with -ffunction-sections and/or -fdata-sections, which these examples for C/C++ do not. If you care about binary size in C or C++ you should probably be compiling with -ffunction-sections/-fdata-sections/-Wl,--gc-sections these days. Sadly, these are not the default.
静态链接的 Rust 在系统层面会放大体积,而动态链接又受 Rust 无稳定 ABI 和频繁升级制约。
谨慎地问:这个问题到底成立吗?我们有数百 GB 甚至 TB 存储,人们也该有像样的 ISP,二进制大小不该担心,对吧?$ find /usr/bin -type f | wc -l 得到 2254 个文件,du -sh /usr/bin 是 445M。如果这些程序都用 Rust 写并静态编译,假设每个只差 600K,/usr/bin 就会变成 1.3G(增大 300%)。但现实中这些程序动态链接 /usr/lib 里的许多库,所以差异会更大,因为库会在所有程序间重复。当然 Rust 也能动态链接,但会碰到另一个问题:没有稳定 ABI(至少当时),而且每 6 周升级 Rust 意味着全部重编译。
glandium查看英文原文
> Just to be cautious: Is it a valid question to ask after all? We have hundreds of gigabytes of storage, if not some terabytes, and people should be using decent ISPs nowadays, so the binary size should not be a concern, right? $ find /usr/bin -type f | wc -l 2254 $ du -sh /usr/bin 445M /usr/bin If all these programs were written in Rust and statically compiled, assuming only a 600K difference by binary, that would make my /usr/bin 1.3G (or 300%) larger. But in reality all those programs are dynamically linked against many libraries in /usr/lib, so the difference would be even bigger, with libraries duplicated between all those programs. Sure, you can dynamically link with Rust too, but then, you hit the other problem that there is no stable ABI (yet?), and that upgrading Rust (every 6 weeks) means recompiling everything.
把所有代码(含汇编)放进 Rust 源文件并启用 LTO,可把固件从约 1MB 降到约 70KB,Rust 大小优化很依赖 LTO。
对写嵌入式固件的人,我最近一个演讲(关于任天堂 64 Rust 开发套件)的一个子要点是:要避免 C/C++ 中常见模式——大部分代码在静态库里,再把可执行文件作为第二步构建。相反,你应把所有代码包括汇编都放在 Rust 源文件里,以便尽可能无痛地生成经过 LTO 的二进制。我的二进制大小从约 1MB 降到约 70KB。如果你在乎二进制大小,Rust 真的很依赖 LTO。
monocasa查看英文原文
For those writing embedded firmware, one of the subpoints of a talk I did recently (about a rust dev kit for the Nintendo 64) was that you want to avoid a standard model where in C and C++ you might have most of your code in a static library and build the executable as a second step. Instead you really want all of your code including your asm in rust source files so it's as painless as possible to generate an LTOed binary. I had binary sizes go from ~1MB to about ~70KB. Rust really depends on LTO if you care about binary size.
2019 年实测 C/Rust Hello World 都变大,Rust 增长主要来自调试信息,strip 后约 187K,与文章去掉 jemalloc 后的数字接近。
我机器上两个可执行文件自 2016 年以来都变大了。Linux 上不优化不 strip:C Hello World 19K;Rust Hello World 1.6M(!)。C 的增长可归因于 ld 的变化:自 ld 2.30 起安全加固默认把只读数据和可执行数据放到不同段。我不明白为什么不该产生三个段(R、RE、RW),但我这里得到四个(R、RE、R、RW)。(有人知道为什么四个吗?)传 -znoseparate-code 关闭后 C 回到文章里的 8K(对 Rust 没影响)。Rust 的增长似乎主要在 debug info。strip 后我得到 187K,和文章去掉 jemalloc(现在默认不再包含)并 strip 后的 121K 相近。有人知道 Rust 从 2016 到 2019 为什么长了这么多吗?
edflsafoiewq查看英文原文
Both executables have grown on my machine since 2016. On Linux, no optimization or stripping * C Hello World - 19K * Rust Hello World - 1.6M (!) The C gain is attributable to a change to ld: it puts read-only data and executable data in separate segments by default as a security hardening measure since ld 2.30. I don't see why this shouldn't produce three segments (R, RE, RW), but here I get four (R, RE, R, RW). (Anyone know why four?) If I pass -znoseparate-code to disable this the C goes back to the 8K shown in the article. (No effect on the Rust). The Rust gain appears to be mostly in debug info. Stripped I get 187K, which is similar to 121K the article gives after stripping and removing jemalloc (which isn't in by default anymore). Does anyone know why Rust has grown so much from 2016 to 2019?
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选