Size of the executable

I don't suppose anyone can do anything about it really but allow me to gripe anyway.

Every time I add yet another "indispensable" crate to my Cargo.toml, the size of the compiled executable leaps up alarmingly. I am already over 5.6MBytes for a fairly simple program.

I would not mid if it was at least truly portable static but it is not even that, viz. problems with openssl lib.

I wonder if there is much duplication and fragmentation of code that could be reused, inherent in such a large crate system?

Have a project that pulls in 109 crates and builds to a binary over 5MB. It's only 2.6MB after stripping the binary of symbols.

I have a few duplicate crates but I don't think they account for much, would be nice if there was a way of fixing that though:

   base64 v0.10.1
   base64 v0.6.0
   base64 v0.9.3
   
   log v0.3.9
   log v0.4.8

   memchr v1.0.2
   memchr v2.2.1

   proc-macro2 v0.4.30
   proc-macro2 v1.0.5

   quote v0.6.13
   quote v1.0.2

   rand v0.3.23
   rand v0.4.6

   safemem v0.2.0
   safemem v0.3.2

   syn v0.15.44
   syn v1.0.5

   unicode-xid v0.1.0
   unicode-xid v0.2.0

   version_check v0.1.5
   version_check v0.9.1

   yansi v0.4.0
   yansi v0.5.0

FYI: Thoughts on Rust bloat | Raph Levien’s blog

Maybe the easiest way to fix duplicates is sending patches for dependent crates using old crates :wink:

1 Like

@Rustafarian Out of curiosity, could you share how large your code is (line count) and what your dependencies are?

@ZiCog version_check v0.1.5 is a way too obsolete. Could you track down the source?

For everyone reading it - please pay some attention to dependabot, this is annoying amazing tool that won't let you fall behind!

1 Like

Seems like there are a bunch of crates depending on an old version of 'version_check', even some big ones.

dependents of vesion_check

@CreepySkeleton
The code I mentioned is only my first baby steps in using Rocket and Postsges. As such it's not very interesting. It only pulls in the crates they need. The code itself is only 200 lines, basically nothing much more than the Rocket examples I'm tinkering with. Like I say baby steps.

It's amusing that something called "version-check", whatever that does, is causing me to grumble about having multiple versions of itself installed :slight_smile:

If you do get around to pinging upstream crates about their dependencies these three are very important to try and update:

   proc-macro2 v0.4.30
   proc-macro2 v1.0.5

   quote v0.6.13
   quote v1.0.2

   syn v0.15.44
   syn v1.0.5

now that proc-macro2, quote and syn are at 1.0 it's a good chance for the ecosystem to try and reduce duplication of them, and with syn commonly hitting 15-30s compile times it's a big help for all developers to only build it once.

1 Like
  • Make sure you run strip, as Rust will put some debug symbols even in release mode, and especially on Linux this is large.
  • Enable LTO
  • Use cargo tree -d to find redundant dependencies (but duplicate syn/quote/proc_macro don't increase file size, as they're compile-time only)
  • Generics can add a lot of bloat quickly. There's cargo-bloat for that.
7 Likes

390 lines of code, and

use serde::{Deserialize};
use tokio::{ prelude::*,io, codec };
use tokio::net::process::Command;
use futures::try_join;
use hyper::{Client, Body, Request};
use hyper_tls::HttpsConnector;
use dirs::home_dir;

Thanks, strip has reduced it to about half the size.