Open
Description
opt-level=z and opt-level=s implicitly enable -Zshare-generics
. While this can have positive binary size impacts, it can also have negative binary size impacts because it reduces LLVMs ability to inline functions.
I have done some analysis on a bunch of projects, comparing the output from size
for different opt levels.
Script
#!/usr/bin/env bash
set -euxo pipefail
bins=$(cargo metadata --format-version 1 | jq '.packages.[].targets.[] | select(.crate_types == ["bin"]) | select(.src_path | contains("index.crates.io") | not) | .name' -r)
echo checking "$bins"
projdir=$(basename "$(realpath .)")
truncate -s 0 results.csv
build() {
type="$1"
rustflags="$2"
wrapper=$(mktemp)
{
echo '#!/usr/bin/env bash'
echo 'r=$1'
echo "shift"
echo exec '$r' '"$@"' "$rustflags"
} > "$wrapper"
chmod +x "$wrapper"
echo "meow"
cat "$wrapper"
cargo clean
bins=$(RUSTC_WRAPPER="$wrapper" cargo build --release --message-format=json-render-diagnostics | jq 'select(.reason == "compiler-artifact") | select(.executable != null) | .executable' -r)
IFS=$'\n'
for bin in $bins; do
echo "$bin"
s=$(size "$bin" | python3 -c 'import sys;x=sys.stdin.read();print(x.split("\n")[1].split()[0])')
echo "$projdir,$(basename "$bin"),$type,$s" >> results.csv
done
rm "$wrapper"
}
build "2" "-Copt-level=2"
build "3" "-Copt-level=3"
build "s" "-Copt-level=s"
build "s-no-share" "-Copt-level=s -Zshare-generics=false"
build "z" "-Copt-level=z"
build "z-no-share" "-Copt-level=z -Zshare-generics=false"
I got the following results:
Results CSV
project,binary,opt-level,text size
rustc-perf,bootstrap-rustc,2,401390
rustc-perf,bootstrap-rustc,3,401518
rustc-perf,bootstrap-rustc,s,401454
rustc-perf,bootstrap-rustc,s-no-share,400286
rustc-perf,bootstrap-rustc,z,402450
rustc-perf,bootstrap-rustc,z-no-share,401562
nextest,build-seed-archive,2,928761
nextest,build-seed-archive,3,928241
nextest,build-seed-archive,s,906783
nextest,build-seed-archive,s-no-share,877006
nextest,build-seed-archive,z,939734
nextest,build-seed-archive,z-no-share,896072
cargo,cargo,2,26769308
cargo,cargo,3,27035766
cargo,cargo,s,23441682
cargo,cargo,s-no-share,22941899
cargo,cargo,z,23003221
cargo,cargo,z-no-share,21949429
nextest,cargo-nextest,2,15327059
nextest,cargo-nextest,3,15331428
nextest,cargo-nextest,s,13378951
nextest,cargo-nextest,s-no-share,13151176
nextest,cargo-nextest,z,13347017
nextest,cargo-nextest,z-no-share,12840776
nextest,cargo-nextest-dup,2,15327071
nextest,cargo-nextest-dup,3,15331440
nextest,cargo-nextest-dup,s,13378951
nextest,cargo-nextest-dup,s-no-share,13151176
nextest,cargo-nextest-dup,z,13347017
nextest,cargo-nextest-dup,z-no-share,12840776
cluelessh,cluelessh,2,3639610
cluelessh,cluelessh,3,3637618
cluelessh,cluelessh,s,3230404
cluelessh,cluelessh,s-no-share,3137054
cluelessh,cluelessh,z,3298182
cluelessh,cluelessh,z-no-share,3160263
cluelessh,cluelessh-agentctl,2,3081768
cluelessh,cluelessh-agentctl,3,3090680
cluelessh,cluelessh-agentctl,s,2752168
cluelessh,cluelessh-agentctl,s-no-share,2668998
cluelessh,cluelessh-agentctl,z,2812587
cluelessh,cluelessh-agentctl,z-no-share,2692805
cluelessh,cluelessh-dos,2,3363901
cluelessh,cluelessh-dos,3,3374685
cluelessh,cluelessh-dos,s,3006511
cluelessh,cluelessh-dos,s-no-share,2909317
cluelessh,cluelessh-dos,z,3069389
cluelessh,cluelessh-dos,z-no-share,2936446
cluelessh,cluelessh-faked,2,3307574
cluelessh,cluelessh-faked,3,3300062
cluelessh,cluelessh-faked,s,2953214
cluelessh,cluelessh-faked,s-no-share,2889345
cluelessh,cluelessh-faked,z,3030640
cluelessh,cluelessh-faked,z-no-share,2939401
cluelessh,cluelessh-key,2,1138744
cluelessh,cluelessh-key,3,1156436
cluelessh,cluelessh-key,s,1031633
cluelessh,cluelessh-key,s-no-share,1003059
cluelessh,cluelessh-key,z,1028888
cluelessh,cluelessh-key,z-no-share,985054
cluelessh,cluelesshd,2,4675529
cluelessh,cluelesshd,3,4666229
cluelessh,cluelesshd,s,4138714
cluelessh,cluelesshd,s-no-share,3995755
cluelessh,cluelesshd,z,4208701
cluelessh,cluelesshd,z-no-share,4024121
cluelessh,cluelesshd-sftp-server,2,2481705
cluelessh,cluelesshd-sftp-server,3,2489701
cluelessh,cluelesshd-sftp-server,s,2244369
cluelessh,cluelesshd-sftp-server,s-no-share,2193279
cluelessh,cluelesshd-sftp-server,z,2304838
cluelessh,cluelesshd-sftp-server,z-no-share,2229436
rustc-perf,collector,2,11333776
rustc-perf,collector,3,11340184
rustc-perf,collector,s,10138920
rustc-perf,collector,s-no-share,9960872
rustc-perf,collector,z,10061628
rustc-perf,collector,z-no-share,9756252
rustc-perf,fetch-latest,2,3041314
rustc-perf,fetch-latest,3,3070746
rustc-perf,fetch-latest,s,2775574
rustc-perf,fetch-latest,s-no-share,2720170
rustc-perf,fetch-latest,z,2766783
rustc-perf,fetch-latest,z-no-share,2687495
hello-world,hello-world,2,344751
hello-world,hello-world,3,344751
hello-world,hello-world,s,344719
hello-world,hello-world,s-no-share,344719
hello-world,hello-world,z,344767
hello-world,hello-world,z-no-share,344767
rustc-perf,import-sqlite,2,7313831
rustc-perf,import-sqlite,3,7395099
rustc-perf,import-sqlite,s,6774471
rustc-perf,import-sqlite,s-no-share,6693379
rustc-perf,import-sqlite,z,6778407
rustc-perf,import-sqlite,z-no-share,6649119
nextest,internal-test,2,339532
nextest,internal-test,3,339532
nextest,internal-test,s,339500
nextest,internal-test,s-no-share,339500
nextest,internal-test,z,339540
nextest,internal-test,z-no-share,339540
Neotron-Pico-BIOS,neotron-pico-bios,2,69320
Neotron-Pico-BIOS,neotron-pico-bios,3,73996
Neotron-Pico-BIOS,neotron-pico-bios,s,52860
Neotron-Pico-BIOS,neotron-pico-bios,s-no-share,52840
Neotron-Pico-BIOS,neotron-pico-bios,z,51192
Neotron-Pico-BIOS,neotron-pico-bios,z-no-share,50960
nextest,passthrough,2,411770
nextest,passthrough,3,411294
nextest,passthrough,s,411125
nextest,passthrough,s-no-share,409746
nextest,passthrough,z,411123
nextest,passthrough,z-no-share,410024
rustc-perf,postgres-to-sqlite,2,7461386
rustc-perf,postgres-to-sqlite,3,7532230
rustc-perf,postgres-to-sqlite,s,6841686
rustc-perf,postgres-to-sqlite,s-no-share,6751134
rustc-perf,postgres-to-sqlite,z,6813466
rustc-perf,postgres-to-sqlite,z-no-share,6664510
ripgrep,rg,2,4378977
ripgrep,rg,3,4435131
ripgrep,rg,s,4013053
ripgrep,rg,s-no-share,3962587
ripgrep,rg,z,3993959
ripgrep,rg,z-no-share,3913056
rust-analyzer,rust-analyzer,2,36815675
rust-analyzer,rust-analyzer,3,36845571
rust-analyzer,rust-analyzer,s,29047888
rust-analyzer,rust-analyzer,s-no-share,30842033
rust-analyzer,rust-analyzer,z,27646232
rust-analyzer,rust-analyzer,z-no-share,28589921
rust-analyzer,rust-analyzer-proc-macro-srv,2,350694
rust-analyzer,rust-analyzer-proc-macro-srv,3,350690
rust-analyzer,rust-analyzer-proc-macro-srv,s,350690
rust-analyzer,rust-analyzer-proc-macro-srv,s-no-share,350550
rust-analyzer,rust-analyzer-proc-macro-srv,z,350610
rust-analyzer,rust-analyzer-proc-macro-srv,z-no-share,350490
rustc-perf,rustc-fake,2,455290
rustc-perf,rustc-fake,3,456474
rustc-perf,rustc-fake,s,452790
rustc-perf,rustc-fake,s-no-share,452150
rustc-perf,rustc-fake,z,453770
rustc-perf,rustc-fake,z-no-share,451770
nextest,rustc-shim,2,398876
nextest,rustc-shim,3,398928
nextest,rustc-shim,s,397635
nextest,rustc-shim,s-no-share,397828
nextest,rustc-shim,z,397343
nextest,rustc-shim,z-no-share,397944
rusty-clock,rusty-clock,2,49052
rusty-clock,rusty-clock,3,51764
rusty-clock,rusty-clock,s,37468
rusty-clock,rusty-clock,s-no-share,37664
rusty-clock,rusty-clock,z,35320
rusty-clock,rusty-clock,z-no-share,35476
rustc-perf,site,2,15569433
rustc-perf,site,3,15585737
rustc-perf,site,s,13880257
rustc-perf,site,s-no-share,13747097
rustc-perf,site,z,13614909
rustc-perf,site,z-no-share,13353497
rustc-perf,sqlite-to-postgres,2,7937442
rustc-perf,sqlite-to-postgres,3,8016754
rustc-perf,sqlite-to-postgres,s,7192830
rustc-perf,sqlite-to-postgres,s-no-share,7104766
rustc-perf,sqlite-to-postgres,z,7154074
rustc-perf,sqlite-to-postgres,z-no-share,6998258
rust-analyzer,xtask,2,1685422
rust-analyzer,xtask,3,1671190
rust-analyzer,xtask,s,1535085
rust-analyzer,xtask,s-no-share,1502505
rust-analyzer,xtask,z,1527938
rust-analyzer,xtask,z-no-share,1479014
Results Table
project | binary | opt-level | text size |
---|---|---|---|
rustc-perf | bootstrap-rustc | 2 | 401390 |
rustc-perf | bootstrap-rustc | 3 | 401518 |
rustc-perf | bootstrap-rustc | s | 401454 |
rustc-perf | bootstrap-rustc | s-no-share | 400286 |
rustc-perf | bootstrap-rustc | z | 402450 |
rustc-perf | bootstrap-rustc | z-no-share | 401562 |
nextest | build-seed-archive | 2 | 928761 |
nextest | build-seed-archive | 3 | 928241 |
nextest | build-seed-archive | s | 906783 |
nextest | build-seed-archive | s-no-share | 877006 |
nextest | build-seed-archive | z | 939734 |
nextest | build-seed-archive | z-no-share | 896072 |
cargo | cargo | 2 | 26769308 |
cargo | cargo | 3 | 27035766 |
cargo | cargo | s | 23441682 |
cargo | cargo | s-no-share | 22941899 |
cargo | cargo | z | 23003221 |
cargo | cargo | z-no-share | 21949429 |
nextest | cargo-nextest | 2 | 15327059 |
nextest | cargo-nextest | 3 | 15331428 |
nextest | cargo-nextest | s | 13378951 |
nextest | cargo-nextest | s-no-share | 13151176 |
nextest | cargo-nextest | z | 13347017 |
nextest | cargo-nextest | z-no-share | 12840776 |
nextest | cargo-nextest-dup | 2 | 15327071 |
nextest | cargo-nextest-dup | 3 | 15331440 |
nextest | cargo-nextest-dup | s | 13378951 |
nextest | cargo-nextest-dup | s-no-share | 13151176 |
nextest | cargo-nextest-dup | z | 13347017 |
nextest | cargo-nextest-dup | z-no-share | 12840776 |
cluelessh | cluelessh | 2 | 3639610 |
cluelessh | cluelessh | 3 | 3637618 |
cluelessh | cluelessh | s | 3230404 |
cluelessh | cluelessh | s-no-share | 3137054 |
cluelessh | cluelessh | z | 3298182 |
cluelessh | cluelessh | z-no-share | 3160263 |
cluelessh | cluelessh-agentctl | 2 | 3081768 |
cluelessh | cluelessh-agentctl | 3 | 3090680 |
cluelessh | cluelessh-agentctl | s | 2752168 |
cluelessh | cluelessh-agentctl | s-no-share | 2668998 |
cluelessh | cluelessh-agentctl | z | 2812587 |
cluelessh | cluelessh-agentctl | z-no-share | 2692805 |
cluelessh | cluelessh-dos | 2 | 3363901 |
cluelessh | cluelessh-dos | 3 | 3374685 |
cluelessh | cluelessh-dos | s | 3006511 |
cluelessh | cluelessh-dos | s-no-share | 2909317 |
cluelessh | cluelessh-dos | z | 3069389 |
cluelessh | cluelessh-dos | z-no-share | 2936446 |
cluelessh | cluelessh-faked | 2 | 3307574 |
cluelessh | cluelessh-faked | 3 | 3300062 |
cluelessh | cluelessh-faked | s | 2953214 |
cluelessh | cluelessh-faked | s-no-share | 2889345 |
cluelessh | cluelessh-faked | z | 3030640 |
cluelessh | cluelessh-faked | z-no-share | 2939401 |
cluelessh | cluelessh-key | 2 | 1138744 |
cluelessh | cluelessh-key | 3 | 1156436 |
cluelessh | cluelessh-key | s | 1031633 |
cluelessh | cluelessh-key | s-no-share | 1003059 |
cluelessh | cluelessh-key | z | 1028888 |
cluelessh | cluelessh-key | z-no-share | 985054 |
cluelessh | cluelesshd | 2 | 4675529 |
cluelessh | cluelesshd | 3 | 4666229 |
cluelessh | cluelesshd | s | 4138714 |
cluelessh | cluelesshd | s-no-share | 3995755 |
cluelessh | cluelesshd | z | 4208701 |
cluelessh | cluelesshd | z-no-share | 4024121 |
cluelessh | cluelesshd-sftp-server | 2 | 2481705 |
cluelessh | cluelesshd-sftp-server | 3 | 2489701 |
cluelessh | cluelesshd-sftp-server | s | 2244369 |
cluelessh | cluelesshd-sftp-server | s-no-share | 2193279 |
cluelessh | cluelesshd-sftp-server | z | 2304838 |
cluelessh | cluelesshd-sftp-server | z-no-share | 2229436 |
rustc-perf | collector | 2 | 11333776 |
rustc-perf | collector | 3 | 11340184 |
rustc-perf | collector | s | 10138920 |
rustc-perf | collector | s-no-share | 9960872 |
rustc-perf | collector | z | 10061628 |
rustc-perf | collector | z-no-share | 9756252 |
rustc-perf | fetch-latest | 2 | 3041314 |
rustc-perf | fetch-latest | 3 | 3070746 |
rustc-perf | fetch-latest | s | 2775574 |
rustc-perf | fetch-latest | s-no-share | 2720170 |
rustc-perf | fetch-latest | z | 2766783 |
rustc-perf | fetch-latest | z-no-share | 2687495 |
hello-world | hello-world | 2 | 344751 |
hello-world | hello-world | 3 | 344751 |
hello-world | hello-world | s | 344719 |
hello-world | hello-world | s-no-share | 344719 |
hello-world | hello-world | z | 344767 |
hello-world | hello-world | z-no-share | 344767 |
rustc-perf | import-sqlite | 2 | 7313831 |
rustc-perf | import-sqlite | 3 | 7395099 |
rustc-perf | import-sqlite | s | 6774471 |
rustc-perf | import-sqlite | s-no-share | 6693379 |
rustc-perf | import-sqlite | z | 6778407 |
rustc-perf | import-sqlite | z-no-share | 6649119 |
nextest | internal-test | 2 | 339532 |
nextest | internal-test | 3 | 339532 |
nextest | internal-test | s | 339500 |
nextest | internal-test | s-no-share | 339500 |
nextest | internal-test | z | 339540 |
nextest | internal-test | z-no-share | 339540 |
Neotron-Pico-BIOS | neotron-pico-bios | 2 | 69320 |
Neotron-Pico-BIOS | neotron-pico-bios | 3 | 73996 |
Neotron-Pico-BIOS | neotron-pico-bios | s | 52860 |
Neotron-Pico-BIOS | neotron-pico-bios | s-no-share | 52840 |
Neotron-Pico-BIOS | neotron-pico-bios | z | 51192 |
Neotron-Pico-BIOS | neotron-pico-bios | z-no-share | 50960 |
nextest | passthrough | 2 | 411770 |
nextest | passthrough | 3 | 411294 |
nextest | passthrough | s | 411125 |
nextest | passthrough | s-no-share | 409746 |
nextest | passthrough | z | 411123 |
nextest | passthrough | z-no-share | 410024 |
rustc-perf | postgres-to-sqlite | 2 | 7461386 |
rustc-perf | postgres-to-sqlite | 3 | 7532230 |
rustc-perf | postgres-to-sqlite | s | 6841686 |
rustc-perf | postgres-to-sqlite | s-no-share | 6751134 |
rustc-perf | postgres-to-sqlite | z | 6813466 |
rustc-perf | postgres-to-sqlite | z-no-share | 6664510 |
ripgrep | rg | 2 | 4378977 |
ripgrep | rg | 3 | 4435131 |
ripgrep | rg | s | 4013053 |
ripgrep | rg | s-no-share | 3962587 |
ripgrep | rg | z | 3993959 |
ripgrep | rg | z-no-share | 3913056 |
rust-analyzer | rust-analyzer | 2 | 36815675 |
rust-analyzer | rust-analyzer | 3 | 36845571 |
rust-analyzer | rust-analyzer | s | 29047888 |
rust-analyzer | rust-analyzer | s-no-share | 30842033 |
rust-analyzer | rust-analyzer | z | 27646232 |
rust-analyzer | rust-analyzer | z-no-share | 28589921 |
rust-analyzer | rust-analyzer-proc-macro-srv | 2 | 350694 |
rust-analyzer | rust-analyzer-proc-macro-srv | 3 | 350690 |
rust-analyzer | rust-analyzer-proc-macro-srv | s | 350690 |
rust-analyzer | rust-analyzer-proc-macro-srv | s-no-share | 350550 |
rust-analyzer | rust-analyzer-proc-macro-srv | z | 350610 |
rust-analyzer | rust-analyzer-proc-macro-srv | z-no-share | 350490 |
rustc-perf | rustc-fake | 2 | 455290 |
rustc-perf | rustc-fake | 3 | 456474 |
rustc-perf | rustc-fake | s | 452790 |
rustc-perf | rustc-fake | s-no-share | 452150 |
rustc-perf | rustc-fake | z | 453770 |
rustc-perf | rustc-fake | z-no-share | 451770 |
nextest | rustc-shim | 2 | 398876 |
nextest | rustc-shim | 3 | 398928 |
nextest | rustc-shim | s | 397635 |
nextest | rustc-shim | s-no-share | 397828 |
nextest | rustc-shim | z | 397343 |
nextest | rustc-shim | z-no-share | 397944 |
rusty-clock | rusty-clock | 2 | 49052 |
rusty-clock | rusty-clock | 3 | 51764 |
rusty-clock | rusty-clock | s | 37468 |
rusty-clock | rusty-clock | s-no-share | 37664 |
rusty-clock | rusty-clock | z | 35320 |
rusty-clock | rusty-clock | z-no-share | 35476 |
rustc-perf | site | 2 | 15569433 |
rustc-perf | site | 3 | 15585737 |
rustc-perf | site | s | 13880257 |
rustc-perf | site | s-no-share | 13747097 |
rustc-perf | site | z | 13614909 |
rustc-perf | site | z-no-share | 13353497 |
rustc-perf | sqlite-to-postgres | 2 | 7937442 |
rustc-perf | sqlite-to-postgres | 3 | 8016754 |
rustc-perf | sqlite-to-postgres | s | 7192830 |
rustc-perf | sqlite-to-postgres | s-no-share | 7104766 |
rustc-perf | sqlite-to-postgres | z | 7154074 |
rustc-perf | sqlite-to-postgres | z-no-share | 6998258 |
rust-analyzer | xtask | 2 | 1685422 |
rust-analyzer | xtask | 3 | 1671190 |
rust-analyzer | xtask | s | 1535085 |
rust-analyzer | xtask | s-no-share | 1502505 |
rust-analyzer | xtask | z | 1527938 |
rust-analyzer | xtask | z-no-share | 1479014 |
It looks like -Zshare-generics is sometimes an improvement and sometimes a regression. It is not immediately clear to me whether enabling it as currently is the right tradeoff of whether it would make more sense to disable it by default.
Metadata
Metadata
Assignees
Labels
Category: Discussion or questions that doesn't represent real issues.Call for partcipation: This issues needs some investigation to determine current statusIssue: Problems and improvements with respect to binary size of generated code.Relevant to the compiler team, which will review and decide on the PR/issue.