codegen-units

Cargo 默认会启用 16 个并行代码生成单元,对编译速度有提升,但是会妨碍某些优化的进行。我们限制到 1:

[profile.release]
codegen-units = 1

level

默认的 release 优化等级为 3,这个等级下编译器会进行循环展开之类的操作以体积膨胀为代价提高程序运行速度。不过这次我们在优化体积,我们不需要以体积为代价的优化。因为我们调整优化等级为 z,意为最小二进制体积:

[profile.release]
opt-level = 'z'

lto

LTO(Link Time Optimization),意为链接时优化。可以消除大量冗余代码,减小二进制体积——代价是更长的链接时间

[profile.release]
lto = true

panic

众所周知,Rust 程序在 panic 时会生成栈回溯,方便定位问题。而这个 flag 会禁用这种行为——请自行权衡使用。

[profile.release]
panic = 'abort'

strip

By default on Linux and macOS, symbol information is included in the compiled .elf file. This information is not needed to properly execute the binary.

Cargo can be configured to automatically strip binaries. Modify Cargo.toml in this way:

[profile.release]
strip = true  # Automatically strip symbols from the binary.

release

cargo build --release

release with build std

# Find your host's target triple. 
$ rustc -vV
...
host: x86_64-apple-darwin

$ cargo +nightly build -Z build-std=std,panic_abort \
    -Z build-std-features=panic_immediate_abort \
    --target x86_64-apple-darwin --release

bloat

cargo install cargo-bloat
$ cargo bloat --release -n 10
    Finished release [optimized] target(s) in 0.19s
    Analyzing target/release/keeprunningd

 File  .text     Size        Crate Name
 1.9%   5.0%  42.9KiB      reqwest h2::proto::connection::Connection<T,P,B>::poll2
 1.1%   2.9%  24.8KiB     dingtalk dingtalk::DingTalk::send_message::{{closure}}
 0.8%   2.1%  17.9KiB      reqwest futures_util::future::try_future::try_chain::TryChain<Fut1,Fut2,Data>::poll
 0.8%   2.0%  17.6KiB         http http::header::name::parse_hdr
 0.6%   1.7%  14.8KiB      reqwest <hyper::client::conn::ProtoClient<T,B> as core::future::future::Future>::poll
 0.6%   1.7%  14.3KiB unicode_bidi std::panicking::begin_panic
 0.6%   1.5%  13.2KiB      reqwest hyper::proto::h1::dispatch::Dispatcher<D,Bs,I,T>::poll_read
 0.5%   1.4%  11.8KiB          std std::sys::unix::process::process_inner::<impl std::sys::unix::process::process_common::Command>::spawn
 0.5%   1.3%  11.5KiB    rust_util rust_util::util_msg::print_color
 0.5%   1.3%  11.5KiB      reqwest <futures_util::future::poll_fn::PollFn<F> as core::future::future::Future>::poll
30.6%  81.2% 697.1KiB              And 3791 smaller methods. Use -n N to show more.
37.7% 100.0% 858.7KiB              .text section size, the file size is 2.2MiB
$ cargo bloat --release --crates
    Finished release [optimized] target(s) in 0.14s
    Analyzing target/release/keeprunningd

 File  .text     Size Crate
11.8%  31.2% 268.1KiB reqwest
10.1%  26.7% 229.7KiB std
 2.9%   7.7%  66.5KiB h2
 1.7%   4.4%  38.0KiB http
 1.4%   3.8%  32.7KiB [Unknown]
 1.3%   3.4%  28.9KiB tokio
 1.2%   3.1%  26.6KiB url
 1.2%   3.1%  26.2KiB hyper
 1.1%   2.9%  24.9KiB dingtalk
 1.0%   2.8%  23.7KiB serde_json
 0.9%   2.4%  20.6KiB term
 0.6%   1.7%  14.6KiB unicode_bidi
 0.6%   1.5%  12.9KiB rust_util
 0.5%   1.2%  10.5KiB keeprunningd
 0.3%   0.9%   8.0KiB sha2
 0.3%   0.9%   7.8KiB mio
 0.2%   0.5%   4.4KiB bytes
 0.2%   0.5%   4.3KiB unicode_normalization
 0.2%   0.5%   4.3KiB security_framework
 0.1%   0.4%   3.2KiB idna
 0.9%   2.5%  21.3KiB And 31 more crates. Use -n N to show more.
37.7% 100.0% 858.7KiB .text section size, the file size is 2.2MiB

Note: numbers above are a result of guesswork. They are not 100% correct and never will be.

deps

cargo install cargo-deps
cargo deps | dot -Tpng > graph.png

cargo-unused-features

https://github.com/TimonPost/cargo-unused-features

Install

cargo install cargo-unused-features

Analyze

unused-features analyze

file

file a.out
$ file a.out
a.out: Mach-O 64-bit executable x86_64
``

nm

nm a.out
$ nm a.out | head
                 U _CFArrayCreate
                 U _CFRelease
                 U _CFRetain
                 U _CFStringCreateWithBytes
                 U _CFStringGetBytes
                 U _CFStringGetCStringPtr
                 U _CFStringGetLength
                 U _SSLClose
                 U _SSLCopyPeerTrust
                 U _SSLCreateContext

strip

strip a.out

upx

$ upx --best --lzma a.out