ron-rs / ron

Rusty Object Notation
https://docs.rs/ron
Apache License 2.0
3.28k stars 123 forks source link

Investigate compile sizes #185

Open kvark opened 5 years ago

kvark commented 5 years ago

Just tried to run cargo-bloat on Wrench (the binary we use for WebRender debugging) and saw this:

kvark@ant /mnt/code/firefox/gfx/wr/wrench $ cargo bloat --release --crates
Compiling ...
Analyzing target/release/wrench

File  .text     Size Crate
1.0%  23.7%   2.0MiB webrender
0.7%  16.7%   1.4MiB ron
0.5%  13.5%   1.1MiB std
0.2%   4.6% 388.4KiB webrender_api
0.2%   4.4% 373.3KiB image
0.2%   4.0% 335.5KiB wrench
0.2%   3.8% 319.6KiB clap
0.1%   2.9% 243.2KiB winit
0.1%   2.8% 233.4KiB gleam
0.1%   2.7% 231.3KiB yaml_rust
0.1%   2.5% 211.6KiB regex_syntax
0.1%   1.7% 140.0KiB regex
0.1%   1.6% 138.3KiB serde
torkleyy commented 5 years ago

Just tried for the decode example:

[thomas@thomas-pc ron]$ cargo bloat --release --example decode --crates
Compiling ...
Analyzing target/release/examples/decode

File  .text     Size Crate
5.7%  62.3% 147.8KiB std
2.0%  21.7%  51.4KiB ron
1.4%  15.1%  35.7KiB [Unknown]
0.0%   0.5%   1.2KiB serde
0.0%   0.4%     925B decode
0.0%   0.0%      54B base64
9.1% 100.0% 237.1KiB .text section size, the file size is 2.5MiB

Maybe the last line is relevant here?

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

I don't really see how ron could take up so much space. Our own code is pretty simple, and we don't have any special dependencies:

[thomas@thomas-pc ron]$ cargo tree
ron v0.5.1 (/home/thomas/Workspace/ron)
├── base64 v0.10.1
│   └── byteorder v1.3.1
├── bitflags v1.0.4
└── serde v1.0.90
    └── serde_derive v1.0.90
        ├── proc-macro2 v0.4.27
        │   └── unicode-xid v0.1.0
        ├── quote v0.6.11
        │   └── proc-macro2 v0.4.27 (*)
        └── syn v0.15.30
            ├── proc-macro2 v0.4.27 (*)
            ├── quote v0.6.11 (*)
            └── unicode-xid v0.1.0 (*)
    [dev-dependencies]
    └── serde_derive v1.0.90 (*)
[dev-dependencies]
├── serde_bytes v0.11.1
│   └── serde v1.0.90 (*)
└── serde_json v1.0.39
    ├── itoa v0.4.3
    ├── ryu v0.2.7
    └── serde v1.0.90 (*)
kvark commented 5 years ago

Interestingly, it doesn't show up when building WR examples, only when building Wrench. The difference is that Wrench enables the serde deserialization attributes on a whole ton of structs, plus the code to actually use them (that calls into Ron).

jrmuizel commented 5 years ago

The size blamed on ron is stuff like:

0.0%   0.1% 10.5KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct
0.0%   0.1% 10.5KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct
0.0%   0.1%  9.4KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct
0.0%   0.1%  8.3KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct
0.0%   0.1%  7.0KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct
0.0%   0.1%  7.0KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct
0.0%   0.1%  6.8KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct
0.0%   0.1%  6.5KiB                   ron? <ron::de::Enum as serde::de::VariantAccess>::struct_variant
0.0%   0.1%  6.3KiB                   ron? <&mut ron::de::Deserializer as serde::de::Deserializer>::deserialize_struct

This is just the actual specialized serialize/deserialize methods.

Also cargo bloat reports compiled size and not compile times.

jrmuizel commented 5 years ago

If you compile with the new mangling scheme you can even get more info about what's going on: RUSTFLAGS="-Z symbol-mangling-version=v0" rustup run nightly cargo bloat --release -n 100 | grep ron

0.0%   0.2% 18.6KiB   [Unknown]? <<webrender[58737326ba1c09f4]::scene_builder::Interners as serde[6276e54a47026ae7]::de::Deserialize>::deserialize::__Visitor as serde[6276e54a47026ae7]::de::Visitor>::visit_map::<ron[d5...
0.0%   0.2% 12.9KiB   [Unknown]? <webrender_api[b9415cac22c9e10f]::display_list::BuiltDisplayList as serde[6276e54a47026ae7]::de::Deserialize>::deserialize::<&mut ron[d53180edc19c75a1]::de
0.0%   0.2% 12.9KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::render_backend::DataStores as serde[6276e...
0.0%   0.1% 11.7KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::texture_cache::TextureCache as serde[6276...
0.0%   0.1%  9.5KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::resource_cache::PlainCacheOwn as serde[62...
0.0%   0.1%  9.0KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::tiling::TextureCacheRenderTarget as serde...
0.0%   0.1%  8.3KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::tiling::Frame as serde[6276e54a47026ae7]:...
0.0%   0.1%  7.4KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::gpu_cache::Texture as serde[6276e54a47026...
0.0%   0.1%  7.4KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::tiling::ColorRenderTarget as serde[6276e5...
0.0%   0.1%  7.2KiB   [Unknown]? <&mut ron[d53180edc19c75a1]::de::Deserializer as serde[6276e54a47026ae7]::de::Deserializer>::deserialize_struct::<<webrender[58737326ba1c09f4]::tiling::AlphaRenderTarget as serde[6276e5...
0.0%   0.1%  7.0KiB   [Unknown]? <ron[d53180edc19c75a1]::de::Enum as serde[6276e54a47026ae7]::de::VariantAccess>::struct_variant::<<<webrender[58737326ba1c09f4]::tiling::RenderPassKind as serde[6276e54a47026ae7]::de::D...
kvark commented 5 years ago

The idea we discussed with @jrmuizel would be to move as much deserialization code as possible from being monomorphised into run-time. For example, we may have a small piece of code parsing RON and generating run-time reflection of a struct (non-generically), so that RON deserialization then works off it.

jrmuizel commented 5 years ago

Yeah, so you could have #[derive(Reflect)] which would try to produce a compact representation of the struct and add a method that returns a reference to this compact representation which implements Deserialize.

juancampa commented 1 month ago

I was just looking at crate sizes for our wasm binary and ron is one of the top ones at 85k (serde-json is ~3X bigger though)

Screenshot 2024-07-12 at 13 31 09

juntyr commented 1 month ago

I think there are some wasm specific tools to analyse what code takes up the most space. Perhaps you could find out what part of RON takes up excessive space?