mcpField
R
rust-profiling

rust-profiling

github.com/mohitmishra786开发269598 次安装18 周前更新
代码仓库

关于 rust-profiling

rust-profiling 是面向 Agent 的 Rust 性能与二进制体积分析指南,涵盖火焰图、perf、分配分析和 Criterion 基准测试等流程。

主要功能

  1. 01使用 cargo-flamegraph 生成火焰图
  2. 02使用 cargo-bloat 分析二进制体积
  3. 03使用 cargo-llvm-lines 分析单态化
  4. 04编写 Criterion 微基准测试
  5. 05使用 perf 和工具分析分配

适用场景

  1. 01查找 Rust 程序的热点路径
  2. 02排查体积异常大的二进制文件
  3. 03测量单态化扩张情况
  4. 04创建并运行 Criterion 基准测试

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mohitmishra786/low-level-dev-skills --skill rust-profiling

安装后在 Claude Code 中输入/rust-profiling确认已加载。

附带文件references/cargo-flamegraph-setup.md

详细介绍

Rust 性能分析

用途

指导 Agent 进行 Rust 性能分析:使用 cargo-flamegraph 生成火焰图、分析二进制文件大小、测量单态化膨胀、编写 Criterion 微基准测试,以及解读包含内联 Rust 栈帧的分析结果。

触发条件

  • “如何为 Rust 程序生成火焰图?”
  • “我的 Rust 二进制文件很大——如何找出原因?”
  • “如何编写 Criterion 基准测试?”
  • “如何测量单态化膨胀?”
  • “Rust 性能不如预期——如何分析?”
  • “如何在 Rust 中使用 perf?”

工作流

1. 为性能分析构建
# Release with debug symbols (needed for readable profiles)
# Cargo.toml:
[profile.release-with-debug]
inherits = "release"
debug = true

cargo build --profile release-with-debug

# Or quick: release + debug info inline
CARGO_PROFILE_RELEASE_DEBUG=true cargo build --release
2. 使用 cargo-flamegraph 生成火焰图
# Install
cargo install flamegraph

# Linux: uses perf (requires perf_event_paranoid ≤ 1)
sudo sh -c 'echo 1 > /proc/sys/kernel/perf_event_paranoid'
cargo flamegraph --bin myapp -- arg1 arg2

# macOS: uses DTrace (requires sudo)
sudo cargo flamegraph --bin myapp -- arg1 arg2

# Profile tests
cargo flamegraph --test mytest -- test_filter

# Profile benchmarks
cargo flamegraph --bench mybench -- --bench

# Output
# Generates flamegraph.svg in current directory
# Open in browser: firefox flamegraph.svg

自定义火焰图选项:

# More samples
cargo flamegraph --freq 1000 --bin myapp

# Filter to specific threads
cargo flamegraph --bin myapp -- args 2>/dev/null

# Using perf directly for more control
perf record -g -F 999 ./target/release-with-debug/myapp args
perf script | stackcollapse-perf.pl | flamegraph.pl > out.svg
3. 使用 cargo-bloat 分析二进制文件大小
# Install
cargo install cargo-bloat

# Show top functions by size
cargo bloat --release -n 20

# Show per-crate size breakdown
cargo bloat --release --crates

# Include only specific crate
cargo bloat --release --filter myapp

# Compare before/after a change
cargo bloat --release --crates > before.txt
# make changes
cargo bloat --release --crates > after.txt
diff before.txt after.txt

典型输出:

 File  .text    Size    Crate Name
 2.4%   3.0% 47.0KiB      std <std macros>
 1.8%   2.3% 35.5KiB   myapp myapp::heavy_module::process
 1.2%   1.5% 23.1KiB    serde serde::de::...
4. 使用 cargo-llvm-lines 分析单态化膨胀
# Install
cargo install cargo-llvm-lines

# Show LLVM IR line counts (proxy for monomorphization)
cargo llvm-lines --release | head -40

# Filter to your crate only
cargo llvm-lines --release | grep '^myapp'

典型输出:

   Lines      Copies  Function name
   85330           1  [LLVM passes]
    7761          92  core::fmt::write
    4672          11  myapp::process::<impl MyTrait for T>
    3201          47  <alloc::vec::Vec<T> as core::ops::Drop>::drop

Copies 计数较高表示单态化扩张。修复方法:

// Before: generic, gets monomorphized for every T
fn process<T: AsRef<[u8]>>(data: T) -> usize {
    do_work(data.as_ref())
}

// After: thin generic wrapper + concrete inner
fn process<T: AsRef<[u8]>>(data: T) -> usize {
    fn inner(data: &[u8]) -> usize { do_work(data) }
    inner(data.as_ref())
}
5. Criterion 微基准测试
# Cargo.toml
[dev-dependencies]
criterion = { version = "0.5", features = ["html_reports"] }

[[bench]]
name = "my_bench"
harness = false
// benches/my_bench.rs
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};

fn bench_process(c: &mut Criterion) {
    // Simple benchmark
    c.bench_function("process 1000 items", |b| {
        let data: Vec<i32> = (0..1000).collect();
        b.iter(|| process(black_box(&data)))  // black_box prevents optimization
    });
}

fn bench_sizes(c: &mut Criterion) {
    let mut group = c.benchmark_group("process_sizes");

    for size in [100, 1000, 10000].iter() {
        let data: Vec<i32> = (0..*size).collect();
        group.bench_with_input(
            BenchmarkId::from_parameter(size),
            &data,
            |b, data| b.iter(|| process(black_box(data))),
        );
    }
    group.finish();
}

criterion_group!(benches, bench_process, bench_sizes);
criterion_main!(benches);
# Run all benchmarks
cargo bench

# Run specific benchmark
cargo bench --bench my_bench

# Run with filter
cargo bench -- process_sizes

# Compare with baseline (save/load)
cargo bench -- --save-baseline before
# make changes
cargo bench -- --baseline before

# View HTML report
open target/criterion/report/index.html
6. 在 Rust 中使用 perf(Linux)
# Record
perf record -g ./target/release-with-debug/myapp args
perf record -g -F 999 ./target/release-with-debug/myapp args  # higher freq

# Report
perf report                     # interactive TUI
perf report --stdio --no-call-graph | head -40   # text

# Annotate specific function
perf annotate myapp::hot_function

# stat (quick counters)
perf stat ./target/release/myapp args

Rust 专用 perf 技巧:

  • 使用 debug = 1 构建(仅包含行号表),加快构建速度并支持行级归因
  • 使用 RUSTFLAGS="-C force-frame-pointers=yes",无需 DWARF 展开即可获得更好的调用图
  • 禁用 ASLR 以确保地址可复现:setarch $(uname -m) -R ./myapp
7. 使用 heaptrack / DHAT 分析分配情况
# heaptrack (Linux)
heaptrack ./target/release/myapp args
heaptrack_print heaptrack.myapp.*.zst | head -50

# DHAT via Valgrind
valgrind --tool=dhat ./target/debug/myapp args
# Open dhat-out.* with dh_view.html

有关火焰图设置和 Criterion 配置,请参阅 references/cargo-flamegraph-setup.md。

相关技能

  • 使用 skills/rust/rustc-basics 配置构建(调试符号、配置文件)
  • 使用 skills/profilers/linux-perf 了解 perf 基础知识
  • 使用 skills/profilers/flamegraphs 阅读和解读火焰图 SVG
  • 使用 skills/profilers/valgrind 通过 massif/DHAT 分析内存分配

评论

支持 Markdown