4 ms·
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
by lifthrasiir 3y ago
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...
- bipson 3y agoDepends 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.
- lifthrasiir 3y agoC/C++ standard library doesn't work in that environment anyway---you typically need a freestanding mode. Rust equvialent is `#[no_std]` which works well for popular boards.
- tialaramex 3y agoTo be technical, Rust deliberately splits out three elements: core (which is necessary for the Rust language and is always provided) alloc (which needs a heap allocator, not applicable if you don't have or don't want one) and then std (which expects an operating system, with features like files and sockets and threads and knowing what the time is) C++ just labels a few specific features as available in a "freestanding" C++ standard library if you have one (on an embedded platform presumably you do). This makes it very easy to know what you're getting in Rust's stdlib in #[no_std] because it's all of core, so e.g. https://doc.rust-lang.org/core/primitive.slice.html#method.sort https://doc.rust-lang.org/core/primitive.slice.html#method.s... vs. https://doc.rust-lang.org/std/primitive.slice.html#method.sort https://doc.rust-lang.org/std/primitive.slice.html#method.so... At first glance those are identical, but no, std is re-exporting every feature core had, but it also gains features, for example the stable sort function family only exist in std because they're using a temporary allocation whereas the unstable (ie equivalent items may be re-ordered) sort provided even in core doesn't do that. Figuring out what you get in your stdlib with C++ often comes down to suck it and see.
- formerly_proven 3y agoAdds up with larger applications using a bunch of distinct binaries or many libraries.
- zer00eyz 3y agoOut in javascript land no one cares about file size or wire time any more (but should) -- Over in C, plenty of people work on things where file size matters. It is a big deal. System constraints (embedded) wire constraints (far away systems where internet is slow and ephemeral), legacy systems where everything is going to be slow even moving that fat file around and you have to be present to update (ATM, ticket, vending machines)... The list goes on. So it may NOT matter for the desk top, or mobile or servers, but that's a tiny fraction of the computing out there.
- lifthrasiir 3y agoI do have a lower threshold for JS apps, which is about 200 KB. This difference accounts for the fact that websites can be streamed while executables can't. I'm not saying that we shouldn't optimize for the size---rather I'm saying the size optimization is not worthwhile under some threshold.
- flohofwoe 3y agoMany MMOs do actually download updated client executables on the fly in the launcher, and that shouldn't make the player wait more than necessary. Even the Steam client has such an automatic update process (and at 200 MBytes this is already in "very annoying" territory IMHO).
- lifthrasiir 3y agoI mean, yes! Games are on the opposite end of the spectrum, where uncompressed assets fly around and 100 MB sounds like very small. These are what I refer to "low-hanging fruits"---I expect a moderate effort can halve the total size for most cases. (I did work on asset file formats back when I was a gamedev.) 400 KB executable is not really a big deal compared to that.
- pdimitar 3y agoI agree with the threshold argument but I guess it differs for all of us. To me 4MB Hello World program is hilariously bad. I want Rust to compete with C. Not be better or even equal to C when it comes to binary sizes, but I want it to be close.
- gred 3y agoI don't have a horse in this race, but a programming language that prides itself on "zero-cost abstractions" and then generates a Hello World program that is 90% wasted space doesn't leave a great impression.
- lifthrasiir 3y agoMost debugging informations are "useless" until they are desparately needed, and this "wasted space" was no exception. So as always, it's another trade-off: will you "waste" some bytes to ease yourself in the future? Cargo already has decided that uninformed people don't want them for the release mode, but it was found that this decision was not uniformly enforced and some debuginfo was still left there. So a new option was added and the default was changed. Happy ending!
- gred 3y agoTrue, but it sounds (nearly?) "useless" based on the description provided by the author: > For example, one thing that was noted is that if we strip the debug symbols by default, then backtraces of release builds will... not contain any debug info, such as line numbers. That is indeed true, but my claim is that these have not been useful anyway. If you have a binary that only has debug symbols for the standard library, but not for your own code, then even though the backtrace will contain some line numbers from stdlib, it will not really give you any useful context [...]
- MrJohz 3y agoThat's true, which is why it's now being stripped.
- oblio 3y ago> "zero-cost abstractions" Zero cost in terms of CPU and RAM usage during execution time.
- 0x000xca0xfe 3y ago
- 0x000xca0xfe 3y agoI work in embedded software and we fight for every megabyte of NAND flash. Multiple smaller executables add up, too. Reducing the binary size is usually more important than performance (and often more important than memory safety, if we are totally honest...). Personally, I hate bloated software just as much as slow software. It's crazy what you can do with 64 kilobytes, let the demoscene blow your mind: https://www.youtube.com/watch?v=ZfuierUvx1A https://www.youtube.com/watch?v=ZfuierUvx1A Would be awesome if compilers could do the same :)
- MrJohz 3y agoIn fairness, this is just doing something automatically that you could have done manually anyway. It's a good change because defaults matter, but it's always been possible to strip debug symbols from Rustc-generated binaries, and all the guides I've seen to reducing binary stuff have mentioned this already. It's also important to remember that in embedded software, you're probably working in a no_std environment anyway, which means that the Rust standard library doesn't need to be included in the binary, which will already significantly reduce the size of your binary. A lot of this is about tradeoffs, and I think the article does a good job of explaining what tradeoffs are relevant here. Yes, binaries should be as small as possible, but shipping multiple compiled standard libraries is also not ideal. The Rust team seem to have gone for a good default for people who are beginning, with lots of ways to tailor the build process for people who don't need debugging information, or who are willing to accept longer install/compile times in exchange for smaller, more optimised binaries.
- 0x000xca0xfe 3y agoI'm not criticizing Rust, I'm criticizing statements that doubt whether the effort to reduce the binary size is worth it. We currently have some nasty C++/boost monstrosities, if Rust can deliver a better development experience AND reliable stack traces AND smaller binaries, it would be HUGE for embedded.
- pdimitar 3y agoStripping debug stuff has always been possible, yes, but that doesn't entirely address the problem of the stdlib being included piecemeal. I want a compiler who throws away everything that's not used in the final binary. If that means that 90% of the stdlib is unused (which is likely true for many small projects) then it should not be included in the binary.
- pdimitar 3y agoMostly because CPU caches matter a lot. Executing 7-8 different Rust binaries, in a loop, that are each north of 10MB+ is bound to be less performant than corresponding smaller programs. Never had the time or dedication to actually verify this but I've been bitten by programs and OS-es that trash the cache too much and I've seen humanly perceivable lags because of it. But maybe in this case I am overreacting.
- nindalf 3y agoWould debug symbols ever be loaded into CPU cache? They'd be in RAM, sure. But why would the CPU ever load them into cache? The way I'm imagining this, and I could be wrong, is that the debug symbols are to one end of the binary. They wouldn't be loaded into cache unless they're going to be used imminently. Another way of saying this is that the change to strip automatically is a small win for for disk space and RAM consumption, but I don't think it's going to improve performance dramatically? I could be wrong about this though.
- pdimitar 3y agoNo, it's more likely that you are correct because it has been a long time since I worked that close to the metal and my info is outdated or downright wrong at this point. Thanks for the nuance. If debug symbols indeed never go into the CPU cache then my remark is completely irrelevant.
- kramerger 3y agoI think most debug info is in its own section. On a real OS the pages are loaded lazily so no (significant) performance hit. Still, I hate big Rust binaries as much as the next guy.
- JohnFen 3y ago> in practice anything below 1 MB seems small enough that you don't need to optimize further. I think that it depends on what sort of machine you're aiming for the binary to run on. I develop for a few platforms where a 1MB executable size would be completely unacceptable.
- pjmlp 3y agoThat won't fit into a ESP32, Arduino or embedded hardware with similar restrictions, leaving the space for C and C++, or the Basic, Pascal compiler vendors still enjoying that space like Mikroe.