7 个版本
0.2.0 | 2024 年 5 月 30 日 |
---|---|
0.1.5 | 2023 年 3 月 16 日 |
0.1.3 | 2023 年 2 月 20 日 |
#41 在 性能分析
每月 241 次下载
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