Rust Performance
Use this skill for Rust optimization work that needs disciplined measurement, targeted changes, and explicit trade-offs, following the methodologies from The Rust Performance Book (https://nnethercote.github.io/perf-book/).
When to Use This Skill
- Runtime performance is too slow in
--release
- Memory usage, allocation rate, or
memcpy traffic is high
- Binary size needs to shrink
- Compile times are slow or regressing
- Profilers show confusing stacks, symbols, or hotspots
HashMap, iterators, I/O, logging, or synchronization appear hot
- Inlining decisions need tuning (function call overhead is hot)
- Machine code inspection needed for bounds checks or missed vectorization
- You need a Rust-specific optimization workflow instead of generic advice
Core Workflow
- Confirm the goal: runtime, memory, binary size, compile times, or a mix.
- Confirm build context before drawing conclusions.
- Runtime claims should come from
--release.
- Profiling builds should usually keep line info.
- Build complaints may be caused by debuginfo, linker choice, or profile settings.
- Measure before changing code.
- Use benchmarks for comparisons and regressions.
- Use profilers for hotspots.
- Use heap profilers when allocation rate or peak memory looks suspicious.
- Use compile-time tools when build speed is the problem.
- Map the symptom to the most likely area.
- Make the smallest high-confidence change first.
- Re-measure after every change.
- Capture fragile wins with comments, tests, or benchmark checks.
Symptom Triage
Slow in dev, acceptable in release
Start with references/build-configuration.md and references/compile-times.md.
- Check debuginfo level
- Check linker choice
- Consider a custom dev profile
- Avoid judging runtime from dev builds
Slow in release too
Start with references/measurement.md, then follow the hotspot.
- Hot CPU path -> measurement, collections, layout, or build tuning
- Hot call overhead -> inlining/build choices, but only after profiling
- Hot bounds or iterator adapters -> collections and iterators
High allocation rate or memory churn
Start with references/allocations-layout.md.
- Look for
clone, to_owned, format!, growing Vec/String, and line-by-line allocation
- Reuse buffers and collections before reaching for exotic changes
HashMap or hashing is hot
Start with references/collections-iterators.md.
- Consider alternative hashers only when HashDoS is not a concern
- Measure hasher changes on real workloads
Slow file or terminal processing
Start with references/io-debugging.md.
- Lock stdout for repeated writes
- Buffer reads and writes
- Reuse line buffers
- Avoid heavy formatting or logging work on cold paths
Builds are slow
Start with references/compile-times.md and references/build-configuration.md.
- Use
cargo build --timings
- Check linker, debuginfo, macro expansion, and LLVM IR bloat
- Reduce unnecessary monomorphization
Multi-core machine is underused
Start with references/parallelism.md.
- Confirm the bottleneck is worth parallelizing
- Check contention, allocator pressure, and memory locality first
Function call overhead is hot
Start with references/inlining-machine-code.md.
- Consider
#[inline] or #[inline(always)] for small hot functions
- Use
#[cold] to outline error paths
- Inspect generated machine code with Compiler Explorer or
cargo-show-asm
Reference Map
references/measurement.md - benchmarking, profiling, profiler hygiene, specific tools
references/build-configuration.md - release settings, LTO, allocators, CPU tuning, binary size, faster builds
references/allocations-layout.md - heap churn, type size, wrapper overhead, data layout, SmallVec/ThinVec
references/collections-iterators.md - iterator costs, std type behavior, hashing trade-offs, alternative hashers
references/io-debugging.md - buffering, line handling, logging, assertion overhead
references/inlining-machine-code.md - inline attributes, cold, outlining, machine code inspection, SIMD
references/parallelism.md - thread-level parallelism and synchronization trade-offs
references/compile-times.md - timings, macros, monomorphization, linker wins
references/general-principles.md - optimization mindset, guardrails, Clippy perf lints
Guardrails
- Do not optimize before establishing a measurement loop.
- Prefer release builds for runtime conclusions.
- Change one variable at a time when benchmarking.
- Prefer simple, idiomatic wins before advanced tricks.
- Treat
unsafe, PGO, SIMD, manual hashing tricks, and aggressive inlining as late-stage tools.
- Call out trade-offs in speed, memory, compile time, debuggability, portability, and clarity.
- Keep non-obvious optimizations documented with the reason they help.
Key Techniques from The Rust Performance Book
Measurement First
Always establish a baseline before making changes:
- Use criterion.rs for statistical benchmarking
- Profile with tools like perf, Valgrind, or VTune
- Measure in
--release mode for runtime conclusions
- Use wall-time, cycles, or instruction counts as appropriate
Build Configuration
Optimize Cargo.toml profiles:
[profile.release]
opt-level = 3
lto = "thin" # or "fat" for maximum optimization
codegen-units = 1 # Better optimization, slower builds
incremental = false # Faster release builds
debuginfo = 0 # Strip debug info for smaller binaries
panic = "abort" # Smaller binaries, faster unwinding
Memory Optimization
- Reuse buffers and allocations
- Prefer stack allocation when possible
- Use object pools for frequent allocations
- Minimize copying with slices and references
- Consider custom allocators for specific workloads
Binary Size Reduction
- Use
panic = "abort" in Cargo.toml
- Enable LTO (Link Time Optimization)
- Strip symbols with
strip or sstrip
- Remove unused dependencies with
cargo tree
- Use
#![no_std] when appropriate for embedded
Compile Time Optimization
- Reduce monomorphization with trait objects
- Limit generic code in hot paths
- Use incremental compilation during development
- Optimize build scripts and procedural macros
- Consider splitting large crates
CPU-Specific Optimizations
- Target specific CPU architectures:
RUSTFLAGS="-C target-cpu=native"
- Enable SIMD with portable packed simd or platform intrinsics
- Profile-guided optimization (PGO) for hot paths
- Consider allocator tuning for your workload
Practical Defaults
- For runtime work: benchmark, profile, then optimize the hottest path.
- For allocation work: use a heap profiler and reuse buffers before redesigning architecture.
- For build work: fix link/debuginfo/profile settings before rewriting code.
- For container or CLI size work: review profile settings,
panic = "abort", and stripping.
- For synchronization concerns: benchmark the actual primitive and contention pattern instead of assuming.
Key Tools
| Tool |
Purpose |
criterion / divan |
Statistical benchmarking |
hyperfine |
CLI program benchmarking |
perf / samply |
Sampling profilers (CPU hotspots) |
DHAT / dhat-rs |
Heap allocation profiling |
Cachegrind |
Instruction counts, cache simulation |
Coz |
Causal profiling (optimization potential) |
cargo-show-asm |
View generated assembly |
cargo llvm-lines |
LLVM IR bloat diagnosis |
cargo build --timings |
Build parallelism visualization |
cargo-wizard |
Interactive build config chooser |
| Compiler Explorer |
Online assembly inspection |
Source: botirk38/botir-skills — distributed by TomeVault.
1---2name: rust-performance-23description: Diagnose and improve Rust runtime speed, memory use, binary size, and compile times with a measurement-first workflow distilled from The Rust Performance Book. Use when profiling hot paths, tuning build settings, reducing allocations, improving I/O, inlining decisions, or fixing slow Rust builds. Use when this capability is needed.4---56# Rust Performance78Use this skill for Rust optimization work that needs disciplined measurement, targeted changes, and explicit trade-offs, following the methodologies from The Rust Performance Book (https://nnethercote.github.io/perf-book/).910## When to Use This Skill1112- Runtime performance is too slow in `--release`13- Memory usage, allocation rate, or `memcpy` traffic is high14- Binary size needs to shrink15- Compile times are slow or regressing16- Profilers show confusing stacks, symbols, or hotspots17- `HashMap`, iterators, I/O, logging, or synchronization appear hot18- Inlining decisions need tuning (function call overhead is hot)19- Machine code inspection needed for bounds checks or missed vectorization20- You need a Rust-specific optimization workflow instead of generic advice2122## Core Workflow23241. Confirm the goal: runtime, memory, binary size, compile times, or a mix.252. Confirm build context before drawing conclusions.26 - Runtime claims should come from `--release`.27 - Profiling builds should usually keep line info.28 - Build complaints may be caused by debuginfo, linker choice, or profile settings.293. Measure before changing code.30 - Use benchmarks for comparisons and regressions.31 - Use profilers for hotspots.32 - Use heap profilers when allocation rate or peak memory looks suspicious.33 - Use compile-time tools when build speed is the problem.344. Map the symptom to the most likely area.355. Make the smallest high-confidence change first.366. Re-measure after every change.377. Capture fragile wins with comments, tests, or benchmark checks.3839## Symptom Triage4041### Slow in dev, acceptable in release4243Start with `references/build-configuration.md` and `references/compile-times.md`.4445- Check debuginfo level46- Check linker choice47- Consider a custom dev profile48- Avoid judging runtime from dev builds4950### Slow in release too5152Start with `references/measurement.md`, then follow the hotspot.5354- Hot CPU path -> measurement, collections, layout, or build tuning55- Hot call overhead -> inlining/build choices, but only after profiling56- Hot bounds or iterator adapters -> collections and iterators5758### High allocation rate or memory churn5960Start with `references/allocations-layout.md`.6162- Look for `clone`, `to_owned`, `format!`, growing `Vec`/`String`, and line-by-line allocation63- Reuse buffers and collections before reaching for exotic changes6465### `HashMap` or hashing is hot6667Start with `references/collections-iterators.md`.6869- Consider alternative hashers only when HashDoS is not a concern70- Measure hasher changes on real workloads7172### Slow file or terminal processing7374Start with `references/io-debugging.md`.7576- Lock stdout for repeated writes77- Buffer reads and writes78- Reuse line buffers79- Avoid heavy formatting or logging work on cold paths8081### Builds are slow8283Start with `references/compile-times.md` and `references/build-configuration.md`.8485- Use `cargo build --timings`86- Check linker, debuginfo, macro expansion, and LLVM IR bloat87- Reduce unnecessary monomorphization8889### Multi-core machine is underused9091Start with `references/parallelism.md`.9293- Confirm the bottleneck is worth parallelizing94- Check contention, allocator pressure, and memory locality first9596### Function call overhead is hot9798Start with `references/inlining-machine-code.md`.99100- Consider `#[inline]` or `#[inline(always)]` for small hot functions101- Use `#[cold]` to outline error paths102- Inspect generated machine code with Compiler Explorer or `cargo-show-asm`103104## Reference Map105106- `references/measurement.md` - benchmarking, profiling, profiler hygiene, specific tools107- `references/build-configuration.md` - release settings, LTO, allocators, CPU tuning, binary size, faster builds108- `references/allocations-layout.md` - heap churn, type size, wrapper overhead, data layout, SmallVec/ThinVec109- `references/collections-iterators.md` - iterator costs, std type behavior, hashing trade-offs, alternative hashers110- `references/io-debugging.md` - buffering, line handling, logging, assertion overhead111- `references/inlining-machine-code.md` - inline attributes, cold, outlining, machine code inspection, SIMD112- `references/parallelism.md` - thread-level parallelism and synchronization trade-offs113- `references/compile-times.md` - timings, macros, monomorphization, linker wins114- `references/general-principles.md` - optimization mindset, guardrails, Clippy perf lints115116## Guardrails117118- Do not optimize before establishing a measurement loop.119- Prefer release builds for runtime conclusions.120- Change one variable at a time when benchmarking.121- Prefer simple, idiomatic wins before advanced tricks.122- Treat `unsafe`, PGO, SIMD, manual hashing tricks, and aggressive inlining as late-stage tools.123- Call out trade-offs in speed, memory, compile time, debuggability, portability, and clarity.124- Keep non-obvious optimizations documented with the reason they help.125126## Key Techniques from The Rust Performance Book127128### Measurement First129130Always establish a baseline before making changes:131- Use criterion.rs for statistical benchmarking132- Profile with tools like perf, Valgrind, or VTune133- Measure in `--release` mode for runtime conclusions134- Use wall-time, cycles, or instruction counts as appropriate135136### Build Configuration137138Optimize Cargo.toml profiles:139```toml140[profile.release]141opt-level = 3142lto = "thin" # or "fat" for maximum optimization143codegen-units = 1 # Better optimization, slower builds144incremental = false # Faster release builds145debuginfo = 0 # Strip debug info for smaller binaries146panic = "abort" # Smaller binaries, faster unwinding147```148149### Memory Optimization150151- Reuse buffers and allocations152- Prefer stack allocation when possible153- Use object pools for frequent allocations154- Minimize copying with slices and references155- Consider custom allocators for specific workloads156157### Binary Size Reduction158159- Use `panic = "abort"` in Cargo.toml160- Enable LTO (Link Time Optimization)161- Strip symbols with `strip` or `sstrip`162- Remove unused dependencies with `cargo tree`163- Use `#![no_std]` when appropriate for embedded164165### Compile Time Optimization166167- Reduce monomorphization with trait objects168- Limit generic code in hot paths169- Use incremental compilation during development170- Optimize build scripts and procedural macros171- Consider splitting large crates172173### CPU-Specific Optimizations174175- Target specific CPU architectures: `RUSTFLAGS="-C target-cpu=native"`176- Enable SIMD with portable packed simd or platform intrinsics177- Profile-guided optimization (PGO) for hot paths178- Consider allocator tuning for your workload179180## Practical Defaults181182- For runtime work: benchmark, profile, then optimize the hottest path.183- For allocation work: use a heap profiler and reuse buffers before redesigning architecture.184- For build work: fix link/debuginfo/profile settings before rewriting code.185- For container or CLI size work: review profile settings, `panic = "abort"`, and stripping.186- For synchronization concerns: benchmark the actual primitive and contention pattern instead of assuming.187188## Key Tools189190| Tool | Purpose |191|------|---------|192| `criterion` / `divan` | Statistical benchmarking |193| `hyperfine` | CLI program benchmarking |194| `perf` / `samply` | Sampling profilers (CPU hotspots) |195| `DHAT` / `dhat-rs` | Heap allocation profiling |196| `Cachegrind` | Instruction counts, cache simulation |197| `Coz` | Causal profiling (optimization potential) |198| `cargo-show-asm` | View generated assembly |199| `cargo llvm-lines` | LLVM IR bloat diagnosis |200| `cargo build --timings` | Build parallelism visualization |201| `cargo-wizard` | Interactive build config chooser |202| Compiler Explorer | Online assembly inspection |203204---205> Source: [botirk38/botir-skills](https://github.com/botirk38/botir-skills) — distributed by [TomeVault](https://tomevault.io).206<!-- tomevault:4.0:skill_md:2026-06-15 -->