ron
ron copied to clipboard
Investigate compile sizes
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
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 (*)
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).
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.
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...
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.
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.