toml icon indicating copy to clipboard operation
toml copied to clipboard

Large increase in binary size after upgrading to v0.7.6

Open ravenclaw900 opened this issue 1 year ago • 4 comments

Recently, I ran a cargo update on my project, and the release binary size jumped ~0.13MB. Relevant CI builds are https://github.com/ravenclaw900/DietPi-Dashboard/actions/runs/5523750813 (old) and https://github.com/ravenclaw900/DietPi-Dashboard/actions/runs/5524904223 (new). I am aware that this was mentioned in https://github.com/toml-rs/toml/issues/340#issuecomment-1363560789 and is a known 'regression'. I also understand that the old toml crate was unmaintained, and didn't fully support TOML 1.0. All that to say, I am in favor of the new parser and what it does, but I'm wondering why the increase in binary size was so large and if there's anything that can be done on either end to reduce the size?

ravenclaw900 avatar Jul 11 '23 22:07 ravenclaw900

Happen to know if that was with or without debug symbols?

I ran cargo bloat on a toml example:

$ cargo bloat --crates --release --example decode
warning: skipping duplicate package `example` found at `/home/epage/.cargo/git/checkouts/libfuzzer-sys-e07fde05820d7bc
6/35ce7d7/example`
    Finished release [optimized + debuginfo] target(s) in 0.02s
    Analyzing target/release/examples/decode

File  .text     Size Crate
2.5%  52.4% 270.7KiB std
2.0%  41.6% 214.5KiB toml_edit
0.1%   1.7%   8.7KiB winnow
0.0%   0.8%   4.3KiB serde
0.0%   0.5%   2.3KiB libtest_mimic
0.0%   0.3%   1.8KiB toml_datetime
0.0%   0.3%   1.4KiB decode
0.0%   0.2%   1.0KiB regex
0.0%   0.1%     555B ignore
0.0%   0.1%     440B memchr
0.0%   0.0%     260B serde_spanned
0.0%   0.0%     133B toml
0.0%   0.0%     109B [Unknown]
0.0%   0.0%      95B hashbrown
0.0%   0.0%      83B indexmap
0.0%   0.0%      38B clap
0.0%   0.0%       5B libc
4.7% 100.0% 516.2KiB .text section size, the file size is 10.6MiB

Re-ran it with toml 0.5

$ cargo bloat --crates --release --example decode
warning: skipping duplicate package `example` found at `/home/epage/.cargo/git/checkouts/libfuzzer-sys-e07fde05820d7bc
6/35ce7d7/example`
   Compiling toml v0.5.10
   Compiling toml v0.7.6 (/home/epage/src/personal/toml/crates/toml)
    Finished release [optimized + debuginfo] target(s) in 2.51s
    Analyzing target/release/examples/decode

File  .text     Size Crate
4.1%  70.6% 270.8KiB std
1.3%  23.4%  89.6KiB toml
0.1%   2.5%   9.7KiB serde
0.0%   0.9%   3.3KiB libtest_mimic
0.0%   0.2%     761B decode
0.0%   0.2%     726B hashbrown
0.0%   0.1%     555B ignore
0.0%   0.1%     440B memchr
0.0%   0.0%     166B indexmap
0.0%   0.0%     109B [Unknown]
0.0%   0.0%       5B libc
5.7% 100.0% 383.4KiB .text section size, the file size is 6.5MiB

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

So

  • old toml: 383 KiB total
  • new toml: 516 KiB total
  • diff: 133 KiB

commit 6e63746862250c6bf35c030d04e1014b1d779b40

After a couple of tweaks (#585), I dropped a little of the size

$ cargo bloat --release --example decode --crates
warning: skipping duplicate package `example` found at `/home/epage/.cargo/git/checkouts/libfuzzer-sys-e07fde05820d7bc
6/35ce7d7/example`
   Compiling toml_edit v0.19.13 (/home/epage/src/personal/toml/crates/toml_edit)
   Compiling toml v0.7.6 (/home/epage/src/personal/toml/crates/toml)
    Finished release [optimized + debuginfo] target(s) in 3.31s
    Analyzing target/release/examples/decode

File  .text     Size Crate
2.5%  53.8% 269.4KiB std
1.9%  40.1% 200.8KiB toml_edit
0.1%   1.7%   8.7KiB winnow
0.0%   0.9%   4.3KiB serde
0.0%   0.5%   2.3KiB libtest_mimic
0.0%   0.4%   1.8KiB toml_datetime
0.0%   0.3%   1.4KiB decode
0.0%   0.2%   1.0KiB regex
0.0%   0.1%     555B ignore
0.0%   0.1%     440B memchr
0.0%   0.1%     260B serde_spanned
0.0%   0.0%     133B toml
0.0%   0.0%     109B [Unknown]
0.0%   0.0%      95B hashbrown
0.0%   0.0%      83B indexmap
0.0%   0.0%      38B clap
0.0%   0.0%       5B libc
4.7% 100.0% 501.0KiB .text section size, the file size is 10.5MiB

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

epage avatar Jul 14 '23 20:07 epage

From looking at the function sizes, my best guesses as to where the size is going

  • Optimizations
  • Error reporting
  • Book keeping for format preserving
  • Lots of small overhead added up
  • Potentially there are multiple copies of functions in the deserialization code that could be reduced down

I should note that the example I was measuring only deserializes so all of the serialization code was optimized out.

epage avatar Jul 14 '23 20:07 epage

All the debug symbols were stripped out in the builds I posted, and it should have also just been deserialization. I'll see if I can get a cargo bloat later, any specific settings that would be helpful?

ravenclaw900 avatar Jul 15 '23 01:07 ravenclaw900

Version 0.19.12:

cargo bloat --crates --release
    Finished release [optimized] target(s) in 0.05s
    Analyzing target/release/dietpi-dashboard

 File  .text     Size Crate
 7.3%  22.2% 455.0KiB std
 6.4%  19.4% 399.5KiB dietpi_dashboard
 2.1%   6.5% 132.7KiB toml_edit
 2.1%   6.4% 131.4KiB tokio
 2.1%   6.3% 128.7KiB rustls
 1.9%   5.9% 122.0KiB ring
 1.5%   4.6%  94.6KiB hyper
 1.2%   3.7%  75.2KiB figment
 1.2%   3.6%  74.8KiB [Unknown]
 0.6%   1.9%  39.8KiB psutil
 0.6%   1.9%  39.3KiB jsonwebtoken
 0.6%   1.8%  37.3KiB serde_json
 0.4%   1.3%  27.7KiB serde
 0.4%   1.3%  27.2KiB tracing_subscriber
 0.4%   1.2%  24.7KiB http
 0.3%   0.9%  17.9KiB anyhow
 0.3%   0.9%  17.7KiB zip
 0.3%   0.8%  16.2KiB data_encoding
 0.2%   0.7%  14.5KiB hashbrown
 0.2%   0.7%  14.2KiB futures_util
 2.3%   7.0% 144.5KiB And 52 more crates. Use -n N to show more.
32.7% 100.0%   2.0MiB .text section size, the file size is 6.1MiB

Version 0.19.14:

cargo bloat --crates --release           
    Finished release [optimized] target(s) in 0.05s
    Analyzing target/release/dietpi-dashboard

 File  .text     Size Crate
 7.3%  22.5% 455.0KiB std
 6.4%  19.7% 399.5KiB dietpi_dashboard
 2.1%   6.5% 131.2KiB tokio
 2.1%   6.3% 128.4KiB rustls
 2.0%   6.0% 122.0KiB ring
 1.6%   4.8%  96.9KiB toml_edit
 1.5%   4.7%  94.4KiB hyper
 1.2%   3.7%  74.8KiB [Unknown]
 1.2%   3.7%  74.6KiB figment
 0.6%   2.0%  39.8KiB psutil
 0.6%   2.0%  39.7KiB jsonwebtoken
 0.6%   1.8%  37.2KiB serde_json
 0.4%   1.4%  27.7KiB serde
 0.4%   1.3%  27.2KiB tracing_subscriber
 0.4%   1.2%  24.5KiB http
 0.3%   0.9%  17.9KiB anyhow
 0.3%   0.9%  17.7KiB zip
 0.3%   0.8%  16.2KiB data_encoding
 0.2%   0.7%  14.5KiB hashbrown
 0.2%   0.7%  14.2KiB futures_util
 2.4%   7.5% 150.9KiB And 55 more crates. Use -n N to show more.
32.5% 100.0%   2.0MiB .text section size, the file size is 6.1MiB

Strangely, binary size increased slightly on every target other than x86_64 after updating to toml_edit 0.19.14, though it's possible this was due to another dependency.

ravenclaw900 avatar Jul 27 '23 20:07 ravenclaw900