top-type-sizes

Nightly rustc provides the print-type-sizes option for printing sizes of all types. It's especially useful for analyzing why futures are soo big, that can hurt performance a lot if such futures are moved.

However, print-type-sizes produces unordered and cluttered output. This crate parses that output, refine it and show top types by size in compact form.

Features: * Sorts types by size. * Deduplicates same types. * Merges variants with similar layout. * Shows layouts in compact form. * Sorts fields by size (-s). * Hides small fields (-h). * Hides wrappers like MaybeUninit and custom ones (-w). * Filters by type names (-f and -e). * Limits output (-l). * Expands specific types with children, heuristically (-p).

Usage

Firstly, install by using cargo install top-type-sizes or clone the repository and run cargo build --release.

Secondly, compile your project: sh $ RUSTFLAGS=-Zprint-type-sizes cargo +nightly build -j 1 > type-sizes.txt * It should be a fresh build without cache. Otherwise, part of info will be lost. * -Zprint-type-sizes requires the nightly compiler. * -j 1 is required to avoid incorrect shuffled output.

Finally, use this crate: sh $ top-type-sizes < type-sizes.txt | less

Help

sh $ top-type-sizes --help

```text top-type-sizes 0.1.5

USAGE: top-type-sizes [FLAGS] [OPTIONS]

FLAGS: --help Prints help information -w, --remove-wrappers Removes wrappers like MaybeUninit -r, --reverse Prints top limit types in ascending order -s, --sort-fields Sorts fields by size and removes paddings -V, --version Prints version information

OPTIONS: -e, --exclude ... Excludes types that match these patterns -p, --expand ... Shows only types that match these patterns and their children, heuristically -f, --filter ... Shows only types that match these patterns -h, --hide-less Hides fields with size less than this value [default: 0] -l, --limit Shows only this number of top types [default: 100] ```

Examples

For instance, let's analyze the tokio/chat example: RUSTFLAGS=-Zprint-type-sizes cargo +nightly build --example chat -j 1 > chat.txt

Once the compiler's output is collected, you can perform multiple queries until results become representative.

Initially, find interesting entry functions: sh top-type-sizes -f chat.rs < chat.txt | less

text ... 1032 [async fn body@examples/chat.rs:174:33: 243:2] align=8 ...

Ok, it's the process function, let's check it and children types.

sh top-type-sizes -w -s -h 33 -p body@examples/chat.rs:174:33 < chat.txt | less

Output: ```text 1032 [async fn body@examples/chat.rs:174:33: 243:2] align=8 1031 variant Suspend2 472 _awaitee align=8 144 lines 40 stream 671 variant Suspend3, Suspend7, Suspend9 152 peer 144 lines 112 _awaitee align=8 40 stream 647 variant Suspend4, Suspend8, Suspend10 152 peer 144 lines 64 __awaitee 40 stream 623 variant Suspend5 152 peer 144 lines 40 stream 40 futures 599 variant Suspend6 152 peer 144 lines 40 stream 583 variant Suspend0 144 lines 40 stream 567 variant Suspend1 144 lines 40 stream 552 variant Unresumed, Returned, Panicked 40 stream

472 [async fn body@examples/chat.rs:155:27: 166:6] align=8 465 variant Suspend0 144 lines 144 lines 112 __awaitee 464 variant Unresumed, Returned, Panicked 144 lines align=8 ... ```

Note: __awaitee means awaiting on an inner future.

Then, you can use -f and -e to refine output even more.