Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

standard library results in enormous binaries #12199

Closed
thestinger opened this issue Feb 12, 2014 · 6 comments
Closed

standard library results in enormous binaries #12199

thestinger opened this issue Feb 12, 2014 · 6 comments
Labels
I-slow Issue: Problems and improvements with respect to performance of generated code. metabug Issues about issues themselves ("bugs about bugs")

Comments

@thestinger
Copy link
Contributor

The initial binary size in C is ~3-8K, while Rust binaries using the standard library start at 2MiB. This problem doesn't stop with the initial code size and continues to grow at a rate much faster than C or C++ applications performing the same work. This is not a Rust compiler issue as it doesn't occur when not using the standard library, even when using an API at the same level of abstraction.

Rust is linking dynamically against the system libraries so there's really no excuse for them being this large. The code size needs to be in the same ballpark as C++ (at most 2x or 3x as large...).

@alexcrichton
Copy link
Member

Changing the title to what the real issue is at hand.

@alexcrichton
Copy link
Member

The vast majority of this size is because these items are included in all rust binaries by default right now:

  • libgreen
  • librustuv
  • libstd
  • libuv
  • rustrt/morestack/small native tidbits

There are a few reasons for the inclusion of these bits:

  • The rust compilation model produces one object file by default. This means that the entire contents of each rust library can be found in one object file. Linkers discard object files that are never used during linking, but because you'll always use at least one symbol from your dependent libraries it means that the linker pulls in the whole library every time. LTO solves this problem.
  • Even with LTO, binaries are quite large. Even when using just libnative instead of libgreen, librustuv, and libuv binaries are still quite large with LTO. The reason for this is because of the I/O design. I/O objects are all created through a trait object, which means that it has a vtable of all its functions. This means that all I/O constructors in libnative/libgreen are forced to be included despite having LTO enabled. There are various ways to get around this, but none I have thought of have been very elegant.

As usual, dynamic linking binaries that are not very large in size. We have not turned this on by default due to the instability of the ABI of a library throughout recompilations.

@thestinger
Copy link
Contributor Author

This issue isn't just about the initial code size when using static linking. The design of the generic functions/types in the standard library causes very bloated code. It will get a bit better when the old vector implementation is gone, but there's a serious lack of code (as in runtime machine code) reuse in most of the modules. I think we can do a lot better with a little thought put into hoisting out some code. The mergefunc pass isn't good enough because LLVM will never hoist out the common parts of generic functions.

@thestinger
Copy link
Contributor Author

Also, fn main() {} isn't using I/O so even with static linking I don't see why the initial code size would be above 4K. I don't think the initial size can be explained by trait objects, as int main(void) {} in C consists of a single function and the Rust equivalent should too.

@pcwalton
Copy link
Contributor

Can you be more specific? It'll be hard to close this issue without specifics.

@thestinger
Copy link
Contributor Author

Replaced with #13097.

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 25, 2022
…ompletions, r=jonas-schievink

fix: Don't show assoc. type binding completions when invalid

Fixes rust-lang/rust-analyzer#12165
flip1995 pushed a commit to flip1995/rust that referenced this issue Feb 8, 2024
Avoid linting redundant closure when callee is marked `#[track_caller]`

Fixes rust-lang#12199

Not sure if there's a nicer way to detect functions marked `#[track_caller]` other than by just looking at its attributes 🤔

changelog: [`redundant_closure`]: [`redundant_closure_for_method_calls`]: avoid linting closures where the function being called is marked `#[track_caller]`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-slow Issue: Problems and improvements with respect to performance of generated code. metabug Issues about issues themselves ("bugs about bugs")
Projects
None yet
Development

No branches or pull requests

3 participants