
Minimizing Rust Binary Size - xanthine
https://github.com/johnthagen/min-sized-rust
======
tiborsaas
Another post for size constraint coding in Rust:

[https://www.codeslow.com/2020/01/writing-4k-intro-in-
rust.ht...](https://www.codeslow.com/2020/01/writing-4k-intro-in-rust.html)

------
ahartmetz
I am surprised that dynamically linking to Rust libstd and other common
libraries is not mentioned. Rust produces (as far as Rust code is concerned,
not sure about libc if used) fully static binaries by default, right?

~~~
pornel
1\. Operating systems don't ship Rust's stdlib (unlike C's), so such binary
would work only on developer's own machine.

2\. Rust doesn't want to commit to a stable ABI yet, so even if an OS wanted
to ship libstd, it'd be logistically difficult due to libstd version having to
exactly match compiler version.

~~~
ahartmetz
1\. seems like a chicken and egg problem. I'm sure that the Debian developers
wouldn't mind shipping it if it made sense (see 2).

2\. is a fair point. At this point in Rust's life I see how avoiding binary
conpatibility questions makes sense. Is anybody even working on it, though?
Otherwise Rust could be making system-provided, dynamically linked libraries
almost impossible due to earlier design decisions without consideration for
BC.

~~~
est31
> Is anybody even working on it, though?

There is no work on MVPs or RFCs for now, but stable ABIs are being discussed
currently: [https://internals.rust-lang.org/t/a-stable-modular-abi-
for-r...](https://internals.rust-lang.org/t/a-stable-modular-abi-for-
rust/12347)

------
Hamuko
> _Cargo defaults its optimization level to 3 for release builds, which
> optimizes the binary for speed. To instruct Cargo to optimize for minimal
> binary size, use the z optimization level in Cargo.toml_

In what scenarios is optimizing for binary size preferred over optimizing for
speed?

~~~
mrich
>In what scenarios is optimizing for binary size preferred over optimizing for
speed?

64kb intros:

[https://www.reddit.com/r/rust/comments/597hhv/logicoma_elysi...](https://www.reddit.com/r/rust/comments/597hhv/logicoma_elysian_1st_place_trsac_2016_pc_64kb/)

[https://www.pouet.net/prod.php?which=69658](https://www.pouet.net/prod.php?which=69658)

~~~
Sharlin
However, 8 kB (the binary size mentioned in the article) is still drastically
too much overhead in a 64k intro, and 4k intros are obviously out of the
question.

------
wyldfire
What about `RUSTC_FLAGS=-Z opt=-Os` (this won't work, I'm sure -- it is a
total mishmash of things I've seen before but -Os is the relevant part).
building your executable, your dependencies and/or libstd w/-Os could really
pay off -- especially if you already have LTO enabled.

------
mkesper
Not all of these should be used except when striving for absolute minimal
sizes.

~~~
dijit
Is there an additional reason?

I see some of them change behaviour or make things complex, but I don't see a
performance impact or anything that indicates software will be more crashy.

~~~
RockIslandLine
Optimizing for size versus performance often eliminates optimizations like
unrolling loops.

At the assembly level, it's sometimes true that a single instruction or
smaller sequence of instructions takes more cpu cycles.

Analyze the different instruction sequences here:

[https://www.nxp.com/docs/en/supporting-
information/MC680X0OP...](https://www.nxp.com/docs/en/supporting-
information/MC680X0OPTAPP.txt)

------
gutino
Sadly there is not before after result example.

~~~
brianm
I was curious about this, so applied the easy ones for an existing tool
([https://github.com/brianm/wsf](https://github.com/brianm/wsf)).

This was not an exhaustive test of optimization combinations, just a single
stack, but the results are interesting!

To read the table: default is no changes in the release profile, ie:

    
    
      [profile.release]
      # opt-level = 'z'
      # lto = true
      # panic = 'abort'
      # codegen-units = 1
    

After that each additional line gets uncommented and rebuilt, then sizes
recorded before and after cargo-strip, so the final line is all four
optimizations applied.

Results:

    
    
                           as generated    after cargo-strip
      default              8675776         5069328
      opt-level = 'z'      9023200         4676112
      lto = true           5943312         3586584
      panic = 'abort'      5062456         3135928
      codegen-units = 1    4747000         3013048
    

Tests run on ubuntu 20.04 (Linux d2836c103a22 5.4.0-37-generic #41-Ubuntu SMP
Wed Jun 3 18:57:02 UTC 2020 x86_64 GNU/Linux) with

    
    
      rustc 1.43.1 (8d69840ab 2020-05-04)  
      cargo 1.43.0 (2cbe9048e 2020-05-03)  
      cargo-strip - reduces the size of binaries using the `strip` command 0.2.2  
    

Fascinatingly, opt-level='z' produced a LARGER binary than the default, before
stripping. That was unexpected.

-Brian

~~~
fouc
Do you think you could get it down to 300kb?

~~~
brianm
I doubt it, the dependency chain is pretty big:
[https://gist.github.com/brianm/066797531d8cc1f1c6c563ea8db7b...](https://gist.github.com/brianm/066797531d8cc1f1c6c563ea8db7b392)

------
naetius
I haven't been following Rust's development much lately, but I'm interested in
understanding what's the state of ABI stability...

~~~
martinhath
Like C++, they basically seem to take the stance of "no".

~~~
steveklabnik
There's some subtleties there, on both the C++ and Rust side. I won't speak to
the C++ stuff, but on the Rust side, it's more "not yet, and we don't know
when, and maybe never, we'll see" than it is "no."

~~~
bluejekyll
It would be accurate to say that the only stable ABI Rust currently supports
is the C FFI ABI, right?

~~~
steveklabnik
I would say that "the Rust ABI is not stable, but Rust also supports other
ABIs." [https://doc.rust-lang.org/stable/reference/items/external-
bl...](https://doc.rust-lang.org/stable/reference/items/external-
blocks.html#abi)

