4 ms·
> Two major hurdles were the initial binary size increase due to bringing in the Rust standard library [...]. They don't say what they did about it, do they? D
by palata 9mo ago
> Two major hurdles were the initial binary size increase due to bringing in the Rust standard library [...].
They don't say what they did about it, do they? Did they just accept it?
- menaerus 9mo agoThe whole article a bit watery which is why I read it as a PR rather than technical presentation
- pornel 9mo agoProbably yes. It's ~300KB per binary, and it's a one-time cost. It can be avoided entirely by disabling the standard library, but that's inconvenient, and usually done only when writing for embedded devices. Usually the problem isn't the size directly, but duplication of Rust dependencies in mixed C++/Rust codebases. If you end up with a sandwich of build systems (when you have library dependencies like C++ => Rust => C++ => Rust), each Rust/Cargo build bundles its copy of libstd and crates. Then you need to either ensure that the linker can clean that up, or use something like Bazel instead of Cargo to make it see both Rust and C++ deps as part of a single dependency tree.
- surajrmal 9mo agoThe size is not fixed. It changes based on how much of the standard library you use. Dynamically linking the standard library is also a valid option in many cases.
- galangalalgol 9mo agoCan it do lto on stdlib even without the nightly build-std flag?
- galangalalgol 9mo agoPosted elsewhere but The default hello world stripped with one codegen unit and panic=abort was 342kB both nightly and stable. Adding lto dropped it 42kB in stable and 40kB in nightly. Adding build-std and only building core did not reduce it any further in size.
- surajrmal 9mo agoI agree, but if you use more of the std library it will contribute more to the final image. I can write a 100 line rust file that ends up being 1MiB (even after lto) because I maximize as much code from the standard library as possible. This is not a knock on rust, but your statements can be a misleading as well. In practice most folks ignore the majority of the standard library so only a few hundred kib of std library end up in their binary.
- galangalalgol 9mo agoBit late, but I made a small program that did network and file io as well as using a variety of containers and running system commands. I couldn't get the default release over 650kB. Using a single codegen unit lto strip and panic=abort got that down to 432kB. Using build-std didn't get it any smaller still. When I added optimization for size was the only way I got build-std to shrink things any further than the other options alone, and that only got me 10kB. My conclusion is that build-std is not a substantial contributor. Using std seems to add 300kB-500kB depending on how much you use. That seems like a lot to me because I am old, but elf binaries add several kB of header so maybe I should stop worrying so much.
- surajrmal 9mo agoIf you build the standard library as a shared library it will be 4+MiB. The portion of that which you end up using is variable but there are ways to accomplish large usage without a great deal if code. I can get a 1.5 MiB binary down to 500KiB by dynamically linking the shared library. It's a net fun because I have many such binaries so it saves size in aggregate. It really does come down to what subset you use though.
- pornel 9mo agoI mean you get one upfront cost for things like allocators, common string manipulation and std::fmt, std::{fs, io, path} helper functions, and gathering of pretty backtraces for panics (which is a surprisingly fiddly task, including ELF+DWARF parsers and gzip to decompress the debug info). A println!("hello world") happens to pull in almost all of it (it panics if stdout is closed). Later code growth is just obviously proportional to what you're doing, and you're not getting a whole new copy of std::fmt every time you call print.
- jsheard 9mo agoWho knows what they did, but there are things which can be done: https://github.com/johnthagen/min-sized-rust https://github.com/johnthagen/min-sized-rust
- sluongng 9mo agoI suspect they just use no_std whenever its applicable https://github.com/facebook/buck2/commit/4a1ccdd36e0de0b69ee185fc9dae8c9d9dfdf3de https://github.com/facebook/buck2/commit/4a1ccdd36e0de0b69ee... https://github.com/facebook/buck2/commit/bee72b29bc9b67b59ba775ce65057f122c75aa70 https://github.com/facebook/buck2/commit/bee72b29bc9b67b59ba... Turn out if you have strong control over the compiler and linker instrumentations, there are a lot of ways to optimize binary size
- dcsommer 9mo agoWe invested a lot into build system optimizations to bring this number down over time, although we did accept on the order of 200 KiB size overhead initially for the stdlib. We initially launched using a Gradle + CMake + Cargo with static linking of the stdlib and some basic linker optimizations. Transitioning WhatsApp Android to Buck2 has helped tremendously to bring the size down, for instance by improving LTO and getting the latest clang toolchain optimizations. Buck2 also hugely improved build times.
- palata 9mo agoThanks!