#size #sorting #type #output #layout #print-type-size

bin+lib top-type-sizes

使 -Zprint-type-size 更加有用

7 个版本

0.2.0 2024 年 5 月 30 日
0.1.5 2023 年 3 月 16 日
0.1.3 2023 年 2 月 20 日

#41性能分析

Download history 80/week @ 2024-05-03 44/week @ 2024-05-10 57/week @ 2024-05-17 126/week @ 2024-05-24 96/week @ 2024-05-31 42/week @ 2024-06-07 88/week @ 2024-06-14 143/week @ 2024-06-21 72/week @ 2024-06-28 86/week @ 2024-07-05 43/week @ 2024-07-12 38/week @ 2024-07-19 91/week @ 2024-07-26 46/week @ 2024-08-02 67/week @ 2024-08-09 30/week @ 2024-08-16

每月 241 次下载

MIT/Apache

29KB
517

top-type-sizes

Nightly rustc 为打印所有类型的尺寸提供了 print-type-sizes 选项。它特别适用于分析为什么 futures 会如此大,如果移动这样的 futures,这可能会大大影响性能。

然而,print-type-sizes 产生无序且杂乱的输出。这个 crate 解析该输出,优化它,并以紧凑的形式显示按尺寸排序的顶级类型。

功能

  • 按大小排序类型。
  • 去重相同类型。
  • 合并布局相似的变体。
  • 以紧凑形式显示布局。
  • 按大小排序字段(-s)。
  • 隐藏小型类型和字段(-h)。
  • 隐藏包装器,如 MaybeUninit 和自定义的(-w)。
  • 按类型名称过滤(-f-e)。
  • 限制输出(-l)。
  • 展开具有子类型的特定类型(-p)。

用法

首先,使用 cargo install top-type-sizes 安装,或者克隆仓库并运行 cargo build --release

其次,编译你的项目

$ RUSTFLAGS=-Zprint-type-sizes cargo +nightly build -j 1 > type-sizes.txt
  • 它应该是一个没有缓存的全新构建。否则,部分信息将会丢失。
  • -Zprint-type-sizes 需要 nightly 编译器。
  • -j 1 是必需的,以避免错误的混乱输出。

最后,使用这个 crate

$ top-type-sizes < type-sizes.txt | less

帮助

$ top-type-sizes --help
top-type-sizes 0.2.0

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

FLAGS:
        --expand-by-size
            Modify the -p/--expand option to expand also by field's size

        --help
            Prints help information

    -w, --remove-wrappers
            Hides wrappers like `MaybeUninit` and `ManuallyDrop`.

            This option removes types having the same layout as an inner type.

    -r, --reverse
            Prints types in descending order.

            This option is applied after the -l/--limit option.

    -s, --sort-fields
            Sorts fields by size and hides paddings.

            Note: enum variants are sorted and merged anyway.

    -V, --version
            Prints version information


OPTIONS:
    -e, --exclude <exclude>...
            Excludes types that match these patterns.

            Patterns are regex (in the regex crate's syntax). Can be provided multiple times.

    -p, --expand <expand>...
            Shows only types that match these patterns and their children.

            It uses two mechanisms to expand types:
             - by field's type name (requires at least nightly 24-03-22)
             - by field's size if the `--expand_by_size` option is enabled

            Note: currently field's type names are provided only for `await`.

            Patterns are regex (in the regex crate's syntax). Can be provided multiple times.

    -f, --filter <filter>...
            Shows only types that match these patterns.

            Patterns are regex (in the regex crate's syntax). Can be provided multiple times.

    -h, --hide-less <hide-less>
            Hides types and fields with size less than this value

    -l, --limit <limit>
            Shows only this number of top types.

            This limit is applied after all other filters.

示例

例如,让我们分析 tokio/chat 示例

RUSTFLAGS=-Zprint-type-sizes cargo +nightly build --example chat -j 1 > chat.txt

一旦收集到编译器的输出,我们就可以执行多个查询,直到结果具有代表性。

最初,显示按大小排序的所有类型,并找到有趣的类型

top-type-sizes < chat.txt | less

例如,如果我们想展开 async fn process() 函数

...
1024 {async fn body of process()} align=8
...

可以使用 -p/--expand 选项来仅显示此函数及其子类型

top-type-sizes -ws -h33 -p 'process\(\)' < chat.txt | less
  • - 隐藏包装器,例如。
    1032 std::mem::MaybeUninit<[async fn body@examples/chat.rs:174:33: 243:2]> align=8
       1032 variant MaybeUninit
           1032 value
    
  • - 按大小排序字段并隐藏填充。
  • -<size> 隐藏所有大小小于指定大小的大小类型和字段。
  • -<pattern> 隐藏所有不包含在 <pattern> 类型中的类型。请注意,编译器并不为所有类型提供字段类型,只为等待者提供。可以使用 --expand-by-size 来按字段大小展开,但它也会显示无关的类型。

输出

1024 {async fn body of process()} align=8
   1023 variant Suspend2
        472 __awaitee align=8 type={async fn body of Peer::new()}
        144 lines
         40 stream (upvar) align=8 offset=0
    663 variant Suspend3, Suspend7, Suspend9
        152 peer
        144 lines
        112 __awaitee align=8 type={async fn body of tokio::sync::Mutex<Shared>::lock()}
         40 stream (upvar) align=8 offset=0
    639 variant Suspend4, Suspend8, Suspend10
        152 peer
        144 lines
         64 __awaitee type={async fn body of Shared::broadcast()}
         40 stream (upvar) align=8 offset=0
    615 variant Suspend5
        152 peer
        144 lines
         40 stream (upvar) align=8 offset=0
         40 futures align=8
    591 variant Suspend6
        152 peer
        144 lines
         40 stream (upvar) align=8 offset=0
    575 variant Suspend0
        144 lines
         40 stream (upvar) align=8 offset=0
    559 variant Suspend1
        144 lines
         40 stream (upvar) align=8 offset=0
     80 variant Unresumed, Returned, Panicked
         40 stream (upvar) align=8 offset=0

472 {async fn body of Peer::new()} align=8
    465 variant Suspend0
        144 lines (upvar) align=8 offset=0
        144 lines
        112 __awaitee type={async fn body of tokio::sync::Mutex<Shared>::lock()}
    152 variant Unresumed, Returned, Panicked
        144 lines (upvar) align=8 offset=0

112 {async fn body of tokio::sync::Mutex<Shared>::lock()} align=8
    104 variant Suspend0
         88 __awaitee type={async block@tokio::sync::Mutex<Shared>::lock::{closure#0}::{closure#0}}
      8 variant Unresumed, Returned, Panicked

88 {async block@tokio::sync::Mutex<Shared>::lock::{closure#0}::{closure#0}} align=8
     80 variant Suspend0
         72 __awaitee type={async fn body of tokio::sync::Mutex<Shared>::acquire()}
      8 variant Unresumed, Returned, Panicked

72 {async fn body of tokio::sync::Mutex<Shared>::acquire()} align=8
     64 variant Suspend0
         56 __awaitee type=tokio::sync::batch_semaphore::Acquire<'_>
      8 variant Unresumed, Returned, Panicked

64 {async fn body of Shared::broadcast()} align=8
     56 variant Unresumed, Returned, Panicked

56 tokio::sync::batch_semaphore::Acquire<'_> align=8
     40 node

注意: __awaitee 表示等待内部future。

然后,我们可以使用 -- 来进一步细化输出。

依赖关系

~5–7MB
~113K SLoC