Rust: Huge binary sizes

Created on 8 Aug 2018  路  7Comments  路  Source: rust-lang/rust

Binaries are huge (3.8M for an empty project).

I tried this code (in a cargo newly generated project's main.rs):

fn main() {}

I expected to see this happen: Compiles to a binary that does nothing, about 500K in size

Instead, this happened: Compiles to a binary that does nothing, but is 3.8M in size

Meta

rustc --version --verbose:

rustc 1.28.0 (9634041f0 2018-07-30)
binary: rustc
commit-hash: 9634041f0e8c0f3191d2867311276f19d0a42564
commit-date: 2018-07-30
host: x86_64-unknown-linux-gnu
release: 1.28.0
LLVM version: 6.0

r2 ./target/release/binary_name and then executing the v command (a hex view) showed me that a large majority of the file where \xff bytes at the end of it.

Additional info

I did a rustup update today. Before empty binaries where 5.1M in size.

Most helpful comment

In case others find this in the future, I've created a min-sized-rust to document all of the ways to reduce Rust binary size.

All 7 comments

There's a number of size optimizations you can make to reduce the size of binaries.

This post is somewhat outdated but summarizes the main reasons; https://lifthrasiir.github.io/rustlog/why-is-a-rust-executable-large.html.

This issue is far too broad; this is currently expected behavior for a variety of reasons. We try to only keep issues open for specific, focused things that can be resolved. Please post to https://users.rust-lang.org/ if you'd like to learn more about why this is true today, and what you can do to change it. Thanks.

things that can be resolved

That sounds alot like 5M overhead for any binary isn't a huge enough issue for a systems programming language.

If the problem is reproducibility:

  1. Setup a fresh raspbian install, current version (2018-06-27 with Kernel 4.14), the "stretch lite" one from this site.
  2. Log into the pi user and curl https://sh.rustup.rs -sSf | sh (taken from https://rustup.rs/)
  3. cargo new --bin huge_bins
  4. cd huge_bins
  5. echo 'fn main () {}' > src/main.rs
  6. cargo build --release

On that (completely reproducable system) I still have 4.4M on a release build. Adding LTO get's me down to only 2.6M.

To get a decently sized executable I have to strip it after building, which brings me down to 324K, at the cost of a backtrace.

When I asked in the IRC about this it seemed that other people had ~500K executables, without the need to turn on LTO, nor stripping their binaries.

If this is truly "intended behaviour", I'll leave. But especially with the whole ecosystem, that does basically everything for you, this feels wrong. I would expect a "--release" binary to be release ready and the defaults to be decent.

Sorry for wasting your time.

z and s opt-level flags were stabilized recently in 1.28
from the release notes,

These optimisations prioritise making smaller binary sizes. z is the same as s with the exception that it does not vectorise loops, which typically results in an even smaller binary.

rationale from stabilization PR #50265,

Since the lastest LLVM upgrade rustc / LLVM does more agressive loop unrolling. This results in increased binary size of embedded / no_std programs: a hundreds of bytes increase, or about a 7x increase,

which unfortunately might not help in the case of fn main () {}, but worth pointing out anyway.

@memoryruins Thanks for the update anyways.

Have a nice day.

In case others find this in the future, I've created a min-sized-rust to document all of the ways to reduce Rust binary size.

Update from my side: The issue has been resolved a while ago. I can't tell when exactly but the 5M overhead is gone.

Was this page helpful?
0 / 5 - 0 ratings