Live data from Hacker News

Making Rust binaries smaller by default

kobzol.github.io

101–110 of 199 posts

Re: Making Rust binaries smaller by default

#101

Earlier quoted context omitted.

All makes sense, but I don't agree with: > This is not always desirable because you may want to catch and recover from panics, particularly in long-running servers. IMHO a panic implies that execution cannot continue under any circumstances, and even any attempts for a graceful shutdown might be futile (if recovery is possible it shouldn't be a panic but done through regular error handling). For a server process the…

I remember my disappointment when I found out panics could be “caught” and that I was still living in the world of exceptions

Oh no, I didn't know this. I'm adding panic = "abort" to all my projects. If I wanted exceptions I wouldn't be using rust.

Re: Making Rust binaries smaller by default

#102

Earlier quoted context omitted.

Also, even in "the" C ABI provided by Rust out of the box there's a certain amount of "Well, this is probably what your C compiler does here, but there's no requirement" rather than an actual hard ABI document. A lot of the "We're ABI stable" claims in C and C++ are "We daren't change anything or stuff breaks" which isn't so much an ABI as it is paralysis and Rust is confident it doesn't want to do that .

> "We're ABI stable" claims in C and C++ are "We daren't change anything or stuff breaks" which isn't so much an ABI as it is paralysis and Rust is confident it doesn't want to do that. For C++, yes sure, but I thought C usually has a pretty well specified ABI on most platforms, no?

I think it's true for common enough platforms, but C is available in too many platforms so I'm not sure it's generally true.

Re: Making Rust binaries smaller by default

#103

It's really a shame that Rust includes the stdlib piecemeal in binary form, debug symbols and all, in every final binary. I do love Rust but binary sizes have always annoyed me greatly and I always had this nagging feeling that part of all programmers don't take Rust seriously because of it. And I actually have witnessed, several times in the last 2-ish years, older-school programmers berating and ignoring Rust on th…

But why? I mean, I'm also obsessed of the byte size from time to time and I do often optimize for the size when it's doable, but in practice anything below 1 MB seems small enough that you don't need to optimize further. There are so many low-hanging fruits when it comes to the Rust binary size...

Re: Making Rust binaries smaller by default

#104
post #58

Earlier quoted context omitted.

These look like sensible defaults to me for release mode. What are the tradeoffs?

opt-level = "z" may be slightly slower than O2/O3. lto = true and lto-units = 1 makes the final linking unbearably slow for large programs. These are still okay, but then `panic = "abort"` shakes a lot of code off by making the final executable unable to print a nice stack trace (even without symbols) and instead immediately traps/abort()-s. Edit: and GP also used "panic-immediate-abort", which also removes the depen…

> These are still okay, but then `panic = "abort"` shakes a lot of code off by making the final executable unable to print a nice stack trace (even without symbols) and instead immediately traps/abort()-s.

I just tried this. The stack traces on panic seem more or less the same with or without panic = "abort" in Cargo.toml.

For example, this program:

    fn main() {
        let v = vec![1, 2, 3];
        v[99];
    }
Compiled with panic="abort" outputs this stack trace:

    $ RUST_BACKTRACE=1 cargo run --release
      Compiling rust-panic v0.1.0 (/Users/seph/temp/rust-panic)
        Finished release [optimized] target(s) in 1.82s
        Running `target/release/rust-panic`
    thread 'main' panicked at src/main.rs:4:6:
    index out of bounds: the len is 3 but the index is 99
    stack backtrace:
      0: _rust_begin_unwind
      1: core::panicking::panic_fmt
      2: core::panicking::panic_bounds_check
      3:  as core::ops::index::Index>::index
      4: rust_panic::main
    note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
    [1]    95405 abort      RUST_BACKTRACE=1 cargo run --release
Weirdly, in this test if I don't strip the binary, I get a larger binary size with panic="abort" than when I leave that out. That is surely due to a bug somewhere.

Re: Making Rust binaries smaller by default

#105

Earlier quoted context omitted.

I remember my disappointment when I found out panics could be “caught” and that I was still living in the world of exceptions

Oh no, I didn't know this. I'm adding panic = "abort" to all my projects. If I wanted exceptions I wouldn't be using rust.

That's actually not too bad if you know you don't need to recover from panic. I kinda hope that `panic = "abort"` is indeed default unless overridden by dependencies, say, tokio...

Re: Making Rust binaries smaller by default

#106
post #58

Earlier quoted context omitted.

These look like sensible defaults to me for release mode. What are the tradeoffs?

opt-level = "z" may be slightly slower than O2/O3. lto = true and lto-units = 1 makes the final linking unbearably slow for large programs. These are still okay, but then `panic = "abort"` shakes a lot of code off by making the final executable unable to print a nice stack trace (even without symbols) and instead immediately traps/abort()-s. Edit: and GP also used "panic-immediate-abort", which also removes the depen…

> `panic = "abort"` shakes a lot of code off by making the final executable unable to print a nice stack trace (even without symbols) and instead immediately traps/abort()-s.

I believe it does print backtraces then terminate, since the backtrace is printed via panic hooks, which happen before the actual unwinding.

Re: Making Rust binaries smaller by default

#107

It's really a shame that Rust includes the stdlib piecemeal in binary form, debug symbols and all, in every final binary. I do love Rust but binary sizes have always annoyed me greatly and I always had this nagging feeling that part of all programmers don't take Rust seriously because of it. And I actually have witnessed, several times in the last 2-ish years, older-school programmers berating and ignoring Rust on th…

But why? I mean, I'm also obsessed of the byte size from time to time and I do often optimize for the size when it's doable, but in practice anything below 1 MB seems small enough that you don't need to optimize further. There are so many low-hanging fruits when it comes to the Rust binary size...

Depends on what you're aiming for.

If we talk about ultra-low-power platforms, e.g. energy-harvesting IoT devices, 1MB is still quite a lot.

If we are going to argue that Rust can compete with C/C++, it needs to have similar performance, also regarding binary size.

Re: Making Rust binaries smaller by default

#108

It's really a shame that Rust includes the stdlib piecemeal in binary form, debug symbols and all, in every final binary. I do love Rust but binary sizes have always annoyed me greatly and I always had this nagging feeling that part of all programmers don't take Rust seriously because of it. And I actually have witnessed, several times in the last 2-ish years, older-school programmers berating and ignoring Rust on th…

> so I guess I'll have to wait several more years

A feature that's landed in Rust nightly will be part of the next beta release (at most 6 weeks away) and then the following full release (exactly 6 weeks away).

For this feature in particular, rustbot added a tag of 1.77.0, which is releasing on 21st March 2024, less than 2 months away.

It's possible you've confused this with more complex features that stay on nightly for a long while they are tested. This is not one of those features.

Re: Making Rust binaries smaller by default

#109

It's really a shame that Rust includes the stdlib piecemeal in binary form, debug symbols and all, in every final binary. I do love Rust but binary sizes have always annoyed me greatly and I always had this nagging feeling that part of all programmers don't take Rust seriously because of it. And I actually have witnessed, several times in the last 2-ish years, older-school programmers berating and ignoring Rust on th…

But why? I mean, I'm also obsessed of the byte size from time to time and I do often optimize for the size when it's doable, but in practice anything below 1 MB seems small enough that you don't need to optimize further. There are so many low-hanging fruits when it comes to the Rust binary size...

Adds up with larger applications using a bunch of distinct binaries or many libraries.

Re: Making Rust binaries smaller by default

#110
post #76

Earlier quoted context omitted.

Building your code (I fixed a few typos, strings -> symbols, fprintf(" -> fprintf(stderr, ") with gcc -s -Os -fuse-ld=lld a.c && ls -al a.out leads to a 5496 bytes ELF though. Which is not much larger than just printf("Hello World!\n"), see sibling comment. I think the point is C "cheated" by including a lot of goodness (format, backtrace etc) in the shared library so they does not have to be copied to each binary.

Thank you for the actual testing (and sorry for typos...). Yes, a C version is small because it dynamically links to libc.so in this case, and I meant to compare against a statically linked version. I primarily wrote this example as a response to the claim that an equivalent---it isn't---C code with musl is very small.

The problem is musl does not support execinfo. For a simple hello world, I managed to statically link with musl to get something with 7888 bytes.
Post reply on HN