[rustdoc] Box ItemKind to reduce the size of Item by jyn514 · Pull Request #80014 · rust-lang/rust (original) (raw)

@nnethercote you should have seen when I started, it was 784 bytes 😆 #79957 (comment)

This is all changing rather rapidly so I'm a little hesitant to put an assert since it will make rebasing harder. After rebasing over master the new change is from 616 to 216.

Also, 280 bytes is still large. Most of the AST types in the compiler itself are less than 100 bytes. Which fields are big?

[src/librustdoc/lib.rs:103] std::mem::size_of::<Span>() = 8
[src/librustdoc/lib.rs:103] std::mem::size_of::<Option<rustc_span::Symbol>>() = 4
[src/librustdoc/lib.rs:103] std::mem::size_of::<Attributes>() = 96
[src/librustdoc/lib.rs:103] std::mem::size_of::<Visibility>() = 40
[src/librustdoc/lib.rs:103] std::mem::size_of::<Box<ItemKind>>() = 8
[src/librustdoc/lib.rs:103] std::mem::size_of::<DefId>() = 8
[src/librustdoc/lib.rs:103] std::mem::size_of::<Option<Stability>>() = 16
[src/librustdoc/lib.rs:103] std::mem::size_of::<Option<rustc_attr::Deprecation>>() = 16
[src/librustdoc/lib.rs:103] std::mem::size_of::<Option<ConstStability>>() = 20

So most of the size is coming from Attributes, Visibility, and (Stability, Deprecation, ConstStability). The last three are from rustc directly. A way I thought of to reduce that size is to calculate them on demand with something like

enum ItemId { Real(DefId), Fake(usize), }

impl Item { fn stability() -> Option { ... } }

and then always return None for fake items. The issue with that is it requires passing a TyCtxt into render, which I have code for, but is a pretty big invasive change.

I do not currently have ideas for reducing the size of Visibility or Attributes.