mcpField
R
rust-profiling

rust-profiling

github.com/mohitmishra786開発269598 回インストール18 週間前に更新
リポジトリ

rust-profiling について

rust-profilingは、Rustの性能やバイナリサイズを調べるエージェント向けスキルです。フレームグラフ、perf、アロケーション分析、Criterionベンチマークの手順を扱います。

主な機能

  1. 01cargo-flamegraphによるフレームグラフ
  2. 02cargo-bloatによるバイナリサイズ分析
  3. 03cargo-llvm-linesによる単相化分析
  4. 04Criterionマイクロベンチマーク
  5. 05perfとアロケーションの分析

活用シーン

  1. 01Rustプログラムのホットパス特定
  2. 02予想外に大きいバイナリの調査
  3. 03単相化による膨張の測定
  4. 04Criterionベンチマークの作成と実行

インストール

コマンドをコピーしてターミナルで実行します。

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

インストール後、Claude Code で/rust-profilingを入力して読み込まれたか確認します。

同梱ファイルreferences/cargo-flamegraph-setup.md

詳細

Rust のプロファイリング

目的

cargo-flamegraph によるフレームグラフ、バイナリサイズの分析、モノモーフィゼーションによる肥大化の測定、Criterion のマイクロベンチマーク、インライン化された Rust フレームを含むプロファイリング結果の解釈を通じて、エージェントが 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 を使用します
  • perf の基本については、skills/profilers/linux-perf を使用します
  • フレームグラフの SVG の読み取りと解釈については、skills/profilers/flamegraphs を使用します
  • massif/DHAT による割り当てのプロファイリングについては、skills/profilers/valgrind を使用します

コメント