m10-performance
actionbook/rust-skills
Measure, identify bottlenecks, then optimize with data structures, allocation strategies, and parallelism.
What is m10-performance?
Performance optimization in Rust requires profiling first to identify actual bottlenecks, then applying targeted improvements. Use this skill when you need to reduce latency, improve throughput, or optimize memory usage—but always measure before optimizing to avoid wasted effort.
- Profile and benchmark code using flamegraph, perf, criterion, and cargo bench to identify true bottlenecks
- Reduce allocations via pre-allocation, object pools, and reuse patterns (Vec::with_capacity, SmallVec)
- Improve cache efficiency by choosing contiguous data structures and sequential access patterns
- Parallelize workloads using rayon or threads for data-parallel tasks
- Eliminate unnecessary copies through references, Cow<T>, and zero-copy designs
- Choose optimal data structures (Vec over HashMap for small sets, avoid LinkedList)
How to install m10-performance
npx skills add https://github.com/actionbook/rust-skills --skill m10-performanceHow to use m10-performance
- 1.Profile your code with flamegraph or perf to identify actual bottlenecks—never guess
- 2.Benchmark baseline performance using cargo bench or criterion in release mode
- 3.Prioritize improvements by impact: algorithm (10x–1000x) > data structure (2x–10x) > allocation (2x–5x) > cache (1.5x–3x)
- 4.Apply targeted optimizations: pre-allocate with Vec::with_capacity, use references instead of clones, choose Vec over HashMap for small sets
- 5.Re-benchmark after each change to verify improvement and avoid premature optimization
Use cases
- Reducing latency in hot code paths identified by profiling
- Improving throughput for batch processing or high-frequency operations
- Optimizing memory usage when working with large datasets or embedded constraints
- Parallelizing CPU-bound computations across multiple cores
- Eliminating allocation overhead in performance-critical loops
- Backend engineers optimizing API response times
- Systems programmers working with performance-critical code
- Data processing engineers handling large datasets
- Game developers targeting frame-rate requirements
- Anyone with measured performance requirements
m10-performance FAQ
No. Make it work first, then measure. Premature optimization wastes effort and adds complexity without proof of benefit.
Debug mode disables optimizations, making benchmarks meaningless. Always use `cargo bench` or `--release` for real performance data.
Use SmallVec when collections are usually small (e.g., < 10 items) to avoid heap allocation; it stores small data inline and spills to heap when needed.
It depends on your access pattern. Vec is cache-friendly for sequential access; HashMap for lookups; arrays for fixed-size data. Profile to know.
Watch for implicit `.clone()` calls, string concatenation in loops, and unnecessary boxing. Use references and `Cow<T>` to avoid copies.
Full instructions (SKILL.md)
Source of truth, from actionbook/rust-skills.
name: m10-performance description: "CRITICAL: Use for performance optimization. Triggers: performance, optimization, benchmark, profiling, flamegraph, criterion, slow, fast, allocation, cache, SIMD, make it faster, 性能优化, 基准测试" user-invocable: false
Performance Optimization
Layer 2: Design Choices
Core Question
What's the bottleneck, and is optimization worth it?
Before optimizing:
- Have you measured? (Don't guess)
- What's the acceptable performance?
- Will optimization add complexity?
Performance Decision → Implementation
| Goal | Design Choice | Implementation |
|---|---|---|
| Reduce allocations | Pre-allocate, reuse | with_capacity, object pools |
| Improve cache | Contiguous data | Vec, SmallVec |
| Parallelize | Data parallelism | rayon, threads |
| Avoid copies | Zero-copy | References, Cow<T> |
| Reduce indirection | Inline data | smallvec, arrays |
Thinking Prompt
Before optimizing:
-
Have you measured?
- Profile first → flamegraph, perf
- Benchmark → criterion, cargo bench
- Identify actual hotspots
-
What's the priority?
- Algorithm (10x-1000x improvement)
- Data structure (2x-10x)
- Allocation (2x-5x)
- Cache (1.5x-3x)
-
What's the trade-off?
- Complexity vs speed
- Memory vs CPU
- Latency vs throughput
Trace Up ↑
To domain constraints (Layer 3):
"How fast does this need to be?"
↑ Ask: What's the performance SLA?
↑ Check: domain-* (latency requirements)
↑ Check: Business requirements (acceptable response time)
| Question | Trace To | Ask |
|---|---|---|
| Latency requirements | domain-* | What's acceptable response time? |
| Throughput needs | domain-* | How many requests per second? |
| Memory constraints | domain-* | What's the memory budget? |
Trace Down ↓
To implementation (Layer 1):
"Need to reduce allocations"
↓ m01-ownership: Use references, avoid clone
↓ m02-resource: Pre-allocate with_capacity
"Need to parallelize"
↓ m07-concurrency: Choose rayon or threads
↓ m07-concurrency: Consider async for I/O-bound
"Need cache efficiency"
↓ Data layout: Prefer Vec over HashMap when possible
↓ Access patterns: Sequential over random access
Quick Reference
| Tool | Purpose |
|---|---|
cargo bench | Micro-benchmarks |
criterion | Statistical benchmarks |
perf / flamegraph | CPU profiling |
heaptrack | Allocation tracking |
valgrind / cachegrind | Cache analysis |
Optimization Priority
1. Algorithm choice (10x - 1000x)
2. Data structure (2x - 10x)
3. Allocation reduction (2x - 5x)
4. Cache optimization (1.5x - 3x)
5. SIMD/Parallelism (2x - 8x)
Common Techniques
| Technique | When | How |
|---|---|---|
| Pre-allocation | Known size | Vec::with_capacity(n) |
| Avoid cloning | Hot paths | Use references or Cow<T> |
| Batch operations | Many small ops | Collect then process |
| SmallVec | Usually small | smallvec::SmallVec<[T; N]> |
| Inline buffers | Fixed-size data | Arrays over Vec |
Common Mistakes
| Mistake | Why Wrong | Better |
|---|---|---|
| Optimize without profiling | Wrong target | Profile first |
| Benchmark in debug mode | Meaningless | Always --release |
| Use LinkedList | Cache unfriendly | Vec or VecDeque |
Hidden .clone() | Unnecessary allocs | Use references |
| Premature optimization | Wasted effort | Make it work first |
Anti-Patterns
| Anti-Pattern | Why Bad | Better |
|---|---|---|
| Clone to avoid lifetimes | Performance cost | Proper ownership |
| Box everything | Indirection cost | Stack when possible |
| HashMap for small sets | Overhead | Vec with linear search |
| String concat in loop | O(n^2) | String::with_capacity or format! |
Related Skills
| When | See |
|---|---|
| Reducing clones | m01-ownership |
| Concurrency options | m07-concurrency |
| Smart pointer choice | m02-resource |
| Domain requirements | domain-* |
Related skills
More from actionbook/rust-skills and the wider catalog.

m11-ecosystem
Navigate Rust crate selection, dependency management, and ecosystem integration decisions.

m12-lifecycle
Design resource creation, usage, and cleanup patterns using RAII, Drop, and lifecycle strategies.

m13-domain-error
Design domain error handling with categorization, recovery strategies, and resilience patterns.

m14-mental-model
Mental models and analogies for understanding Rust ownership, borrowing, and core concepts.

m15-anti-pattern
Identify and refactor Rust code anti-patterns during review.

meta-cognition-parallel
Three-layer parallel meta-cognition analysis for Rust questions—language mechanics, design choices, and domain constraints.