optimizing binary size

2022-02-20 ยท 2 min read

Setup #

# for running cargo bloat
$ RUSTFLAGS="-C target-cpu=native" c install cargo-bloat

# for running cargo size (among other things)
$ rustup component add llvm-tools-preview
$ rustup +nightly component add llvm-tools-preview # (for strip=symbols)
$ RUSTFLAGS="-C target-cpu=native" c install cargo-binutils

TL;DR #

# compile and sort functions by binary size
$ cargo bloat --release -n 100

# only like 20-25% of the binary size seems to be our code or other relevant
# stuff like ndarray. The rest seems to be mostly panic and fmt
# infrastructure...

# compile and sort crates by binary size
$ cargo bloat --release --crates

# print the size of each section in the binary
$ cargo size --bin kcddice --release -- -A

# strip debug info and all symbols (requires nightly) then print section size
$ RUSTFLAGS="-Z strip=symbols -C target-cpu=native" cargo +nightly \
	size --bin kcddice --release -- -A

# before: 1.8 MiB! looking at the sections, it's mostly debug info.
# "-Z strip=symbols" brings this down to like 330-400 KiB (depending on
# other flags etc...)

# TODO: cargo-binutils also installed `cargo strip`; maybe that's helpful?

Cargo.toml #

[profile.release]
codegen-units = 1
lto = true
panic = "abort"
# opt-level = "s" # optimize for size, but still unroll
# opt-level = "z" # optimize for size, no unrolling at all
opt-level = 3
debug = 0

WASM #

https://rustwasm.github.io/twiggy/