Rust Profiling

mohitmishra786/low-level-dev-skills/skills/rust/rust-profiling

作者 mohitmishra786bdc58472fa9f无许可证253 个星标收录于 2026年10月9日更新于 2026年10月9日仓库3个月前更新

Rust profiling skill for performance analysis. Use when generating flamegraphs from Rust binaries, measuring monomorphization bloat with cargo-llvm-lines, analysing binary size with cargo-bloat, microbenchmarking with Criterion, or interpreting inlined frames in profiles. Activates on queries about cargo flamegraph, cargo-bloat, cargo-llvm-lines, Criterion benchmarks, Rust performance profiling, or binary size analysis.

AI 生成的概览

指导 Rust 性能分析,包括火焰图、二进制体积分析、单态化膨胀检查和 Criterion 基准测试。

功能
该技能提供 Rust 程序性能分析的指导:使用调试符号构建、用 cargo-flamegraph 生成火焰图、用 cargo-bloat 分析二进制体积、用 cargo-llvm-lines 测量单态化膨胀、编写 Criterion 微基准测试,以及使用 perf、heaptrack 和 DHAT。它输出的是说明和命令示例而非脚本,并指向一份关于火焰图配置和 Criterion 配置的参考文档。
适用场景
当 Rust 二进制运行缓慢或体积异常大、需要生成火焰图、测量单态化或二进制体积、编写 Criterion 基准测试,或解读性能分析中的内联帧时使用。
运行要求
需要 Rust 工具链和 Cargo。分析工具需另行安装:cargo-flamegraph、cargo-bloat、cargo-llvm-lines、作为开发依赖的 Criterion,以及可选的 perf、heaptrack 和 Valgrind/DHAT。Linux 上生成火焰图需要 perf,且 perf_event_paranoid 不高于 1;macOS 上使用 DTrace 并需要 sudo。不附带脚本,只有说明和一份参考文档。

Rust Profiling

Purpose

Guide agents through Rust performance profiling: flamegraphs via cargo-flamegraph, binary size analysis, monomorphization bloat measurement, Criterion microbenchmarks, and interpreting profiling results with inlined Rust frames.

Triggers

  • "How do I generate a flamegraph for a Rust program?"
  • "My Rust binary is huge — how do I find what's causing it?"
  • "How do I write Criterion benchmarks?"
  • "How do I measure monomorphization bloat?"
  • "Rust performance is worse than expected — how do I profile it?"
  • "How do I use perf with Rust?"

Workflow

1. Build for profiling

bash
# 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 inlineCARGO_PROFILE_RELEASE_DEBUG=true cargo build --release

2. Flamegraphs with cargo-flamegraph

bash
# Installcargo 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 testscargo flamegraph --test mytest -- test_filter
# Profile benchmarkscargo flamegraph --bench mybench -- --bench
# Output# Generates flamegraph.svg in current directory# Open in browser: firefox flamegraph.svg

Custom flamegraph options:

bash
# More samplescargo flamegraph --freq 1000 --bin myapp
# Filter to specific threadscargo flamegraph --bin myapp -- args 2>/dev/null
# Using perf directly for more controlperf record -g -F 999 ./target/release-with-debug/myapp argsperf script | stackcollapse-perf.pl | flamegraph.pl > out.svg

3. Binary size analysis with cargo-bloat

bash
# Installcargo install cargo-bloat
# Show top functions by sizecargo bloat --release -n 20
# Show per-crate size breakdowncargo bloat --release --crates
# Include only specific cratecargo bloat --release --filter myapp
# Compare before/after a changecargo bloat --release --crates > before.txt# make changescargo bloat --release --crates > after.txtdiff before.txt after.txt

Typical output:

 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. Monomorphization bloat with cargo-llvm-lines

bash
# Installcargo install cargo-llvm-lines
# Show LLVM IR line counts (proxy for monomorphization)cargo llvm-lines --release | head -40
# Filter to your crate onlycargo llvm-lines --release | grep '^myapp'

Typical output:

   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

High Copies count = monomorphization expansion. Fix:

rust
// Before: generic, gets monomorphized for every Tfn process<T: AsRef<[u8]>>(data: T) -> usize {    do_work(data.as_ref())}
// After: thin generic wrapper + concrete innerfn process<T: AsRef<[u8]>>(data: T) -> usize {    fn inner(data: &[u8]) -> usize { do_work(data) }    inner(data.as_ref())}

5. Criterion microbenchmarks

toml
# Cargo.toml[dev-dependencies]criterion = { version = "0.5", features = ["html_reports"] }
[[bench]]name = "my_bench"harness = false
rust
// benches/my_bench.rsuse 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);
bash
# Run all benchmarkscargo bench
# Run specific benchmarkcargo bench --bench my_bench
# Run with filtercargo bench -- process_sizes
# Compare with baseline (save/load)cargo bench -- --save-baseline before# make changescargo bench -- --baseline before
# View HTML reportopen target/criterion/report/index.html

6. perf with Rust (Linux)

bash
# Recordperf record -g ./target/release-with-debug/myapp argsperf record -g -F 999 ./target/release-with-debug/myapp args  # higher freq
# Reportperf report                     # interactive TUIperf report --stdio --no-call-graph | head -40   # text
# Annotate specific functionperf annotate myapp::hot_function
# stat (quick counters)perf stat ./target/release/myapp args

Rust-specific perf tips:

  • Build with debug = 1 (line tables only) for faster builds with line-level attribution
  • Use RUSTFLAGS="-C force-frame-pointers=yes" for better call graphs without DWARF unwinding
  • Disable ASLR for reproducible addresses: setarch $(uname -m) -R ./myapp

7. heaptrack / DHAT for allocations

bash
# heaptrack (Linux)heaptrack ./target/release/myapp argsheaptrack_print heaptrack.myapp.*.zst | head -50
# DHAT via Valgrindvalgrind --tool=dhat ./target/debug/myapp args# Open dhat-out.* with dh_view.html

For flamegraph setup and Criterion configuration, see references/cargo-flamegraph-setup.md [blocked].

Related skills

  • Use skills/rust/rustc-basics for build configuration (debug symbols, profiles)
  • Use skills/profilers/linux-perf for perf fundamentals
  • Use skills/profilers/flamegraphs for reading and interpreting flamegraph SVGs
  • Use skills/profilers/valgrind for allocation profiling with massif/DHAT

来源与署名

来源:mohitmishra786/low-level-dev-skills位于skills/rust/rust-profiling提交bdc5847

许可证: 无许可证

内容归原作者所有。SourceWeft 从公开仓库中收录这些内容。

举报或申请下架