📦 deps(thirdparty): update snapshots
This commit is contained in:
@@ -0,0 +1,363 @@
|
||||
---
|
||||
name: performance
|
||||
description: This skill should be used when profiling code, optimizing bottlenecks, benchmarking, or when "performance", "profiling", "optimization", or "--perf" are mentioned.
|
||||
metadata:
|
||||
version: "1.0.0"
|
||||
---
|
||||
|
||||
# Performance Engineering
|
||||
|
||||
Evidence-based performance optimization → measure → profile → optimize → validate.
|
||||
|
||||
<when_to_use>
|
||||
|
||||
- Profiling slow code paths or bottlenecks
|
||||
- Identifying memory leaks or excessive allocations
|
||||
- Optimizing latency-critical operations (P95, P99)
|
||||
- Benchmarking competing implementations
|
||||
- Database query optimization
|
||||
- Reducing CPU usage in hot paths
|
||||
- Improving throughput (RPS, ops/sec)
|
||||
|
||||
NOT for: premature optimization, optimization without measurement, guessing at bottlenecks
|
||||
|
||||
</when_to_use>
|
||||
|
||||
<iron_law>
|
||||
|
||||
NO OPTIMIZATION WITHOUT MEASUREMENT
|
||||
|
||||
**Required workflow:**
|
||||
1. Measure baseline performance with realistic workload
|
||||
2. Profile to identify actual bottleneck
|
||||
3. Optimize the bottleneck (not what you think is slow)
|
||||
4. Measure again to verify improvement
|
||||
5. Document gains and tradeoffs
|
||||
|
||||
Optimizing unmeasured code wastes time and introduces bugs.
|
||||
|
||||
</iron_law>
|
||||
|
||||
<stages>
|
||||
|
||||
Load the **maintain-tasks** skill for stage tracking:
|
||||
|
||||
**Stage 1: Establishing baseline**
|
||||
- content: "Establish performance baseline with realistic workload"
|
||||
- activeForm: "Establishing performance baseline"
|
||||
|
||||
**Stage 2: Profiling bottlenecks**
|
||||
- content: "Profile code to identify actual bottlenecks"
|
||||
- activeForm: "Profiling code to identify bottlenecks"
|
||||
|
||||
**Stage 3: Analyzing root cause**
|
||||
- content: "Analyze profiling data to determine root cause"
|
||||
- activeForm: "Analyzing profiling data"
|
||||
|
||||
**Stage 4: Implementing optimization**
|
||||
- content: "Implement targeted optimization for identified bottleneck"
|
||||
- activeForm: "Implementing optimization"
|
||||
|
||||
**Stage 5: Validating improvement**
|
||||
- content: "Measure performance gains and verify no regressions"
|
||||
- activeForm: "Validating performance improvement"
|
||||
|
||||
</stages>
|
||||
|
||||
<metrics>
|
||||
|
||||
## Key Performance Indicators
|
||||
|
||||
**Latency (response time):**
|
||||
- P50 (median) — typical case
|
||||
- P95 — most users
|
||||
- P99 — tail latency
|
||||
- P99.9 — outliers
|
||||
- TTFB — time to first byte
|
||||
- TTLB — time to last byte
|
||||
|
||||
**Throughput:**
|
||||
- RPS — requests per second
|
||||
- ops/sec — operations per second
|
||||
- bytes/sec — data transfer rate
|
||||
- queries/sec — database throughput
|
||||
|
||||
**Memory:**
|
||||
- Heap usage — allocated memory
|
||||
- GC frequency — garbage collection pauses
|
||||
- GC duration — stop-the-world time
|
||||
- Allocation rate — memory churn
|
||||
- Resident set size (RSS) — total memory
|
||||
|
||||
**CPU:**
|
||||
- CPU time — total compute
|
||||
- Wall time — elapsed time
|
||||
- Hot paths — frequently executed code
|
||||
- Time complexity — algorithmic efficiency
|
||||
- CPU utilization — percentage used
|
||||
|
||||
**Always measure:**
|
||||
- Before optimization (baseline)
|
||||
- After optimization (improvement)
|
||||
- Under realistic load (not toy data)
|
||||
- Multiple runs (account for variance)
|
||||
|
||||
</metrics>
|
||||
|
||||
<profiling_tools>
|
||||
|
||||
## TypeScript/Bun
|
||||
|
||||
**Built-in timing:**
|
||||
|
||||
```typescript
|
||||
console.time('operation')
|
||||
// ... code to measure
|
||||
console.timeEnd('operation')
|
||||
|
||||
// High precision
|
||||
const start = Bun.nanoseconds()
|
||||
// ... code to measure
|
||||
const elapsed = Bun.nanoseconds() - start
|
||||
console.log(`Took ${elapsed / 1_000_000}ms`)
|
||||
```
|
||||
|
||||
**Performance API:**
|
||||
|
||||
```typescript
|
||||
const mark1 = performance.mark('start')
|
||||
// ... code to measure
|
||||
const mark2 = performance.mark('end')
|
||||
performance.measure('operation', 'start', 'end')
|
||||
const measure = performance.getEntriesByName('operation')[0]
|
||||
console.log(`Duration: ${measure.duration}ms`)
|
||||
```
|
||||
|
||||
**Memory profiling:**
|
||||
- Chrome DevTools → Memory tab → heap snapshots
|
||||
- Node.js `--inspect` flag + Chrome DevTools
|
||||
- `process.memoryUsage()` for RSS/heap tracking
|
||||
|
||||
**CPU profiling:**
|
||||
- Chrome DevTools → Performance tab → record session
|
||||
- Node.js `--prof` flag + `node --prof-process`
|
||||
- Flamegraphs for visualization
|
||||
|
||||
## Rust
|
||||
|
||||
**Benchmarking:**
|
||||
|
||||
```rust
|
||||
#[cfg(test)]
|
||||
mod benches {
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion};
|
||||
|
||||
fn benchmark_function(c: &mut Criterion) {
|
||||
c.bench_function("my_function", |b| {
|
||||
b.iter(|| my_function(black_box(42)))
|
||||
});
|
||||
}
|
||||
|
||||
criterion_group!(benches, benchmark_function);
|
||||
criterion_main!(benches);
|
||||
}
|
||||
```
|
||||
|
||||
**Profiling:**
|
||||
- `cargo bench` — criterion benchmarks
|
||||
- `perf record` + `perf report` — Linux profiling
|
||||
- `cargo flamegraph` — visual flamegraphs
|
||||
- `cargo bloat` — binary size analysis
|
||||
- `valgrind --tool=callgrind` — detailed profiling
|
||||
- `heaptrack` — memory profiling
|
||||
|
||||
**Instrumentation:**
|
||||
|
||||
```rust
|
||||
use std::time::Instant;
|
||||
|
||||
let start = Instant::now();
|
||||
// ... code to measure
|
||||
let duration = start.elapsed();
|
||||
println!("Took: {:?}", duration);
|
||||
```
|
||||
|
||||
</profiling_tools>
|
||||
|
||||
<optimization_patterns>
|
||||
|
||||
## Algorithm Improvements
|
||||
|
||||
**Time complexity:**
|
||||
- O(n²) → O(n log n) — sorting, searching
|
||||
- O(n) → O(log n) — binary search, trees
|
||||
- O(n) → O(1) — hash maps, memoization
|
||||
|
||||
**Space-time tradeoffs:**
|
||||
- Cache computed results (memoization)
|
||||
- Precompute expensive operations
|
||||
- Index data for faster lookup
|
||||
- Use hash maps for O(1) access
|
||||
|
||||
## Memory Optimization
|
||||
|
||||
**Reduce allocations:**
|
||||
|
||||
```typescript
|
||||
// Bad: creates new array each iteration
|
||||
for (const item of items) {
|
||||
const results = []
|
||||
results.push(process(item))
|
||||
}
|
||||
|
||||
// Good: reuse array
|
||||
const results = []
|
||||
for (const item of items) {
|
||||
results.push(process(item))
|
||||
}
|
||||
```
|
||||
|
||||
```rust
|
||||
// Bad: allocates String every time
|
||||
fn format_user(name: &str) -> String {
|
||||
format!("User: {}", name)
|
||||
}
|
||||
|
||||
// Good: reuses buffer
|
||||
fn format_user(name: &str, buf: &mut String) {
|
||||
buf.clear();
|
||||
buf.push_str("User: ");
|
||||
buf.push_str(name);
|
||||
}
|
||||
```
|
||||
|
||||
**Memory pooling:**
|
||||
- Reuse expensive objects (connections, buffers)
|
||||
- Object pools for frequently allocated types
|
||||
- Arena allocators for batch allocations
|
||||
|
||||
**Lazy evaluation:**
|
||||
- Compute only when needed
|
||||
- Stream processing vs loading all data
|
||||
- Iterators over materialized collections
|
||||
|
||||
## I/O Optimization
|
||||
|
||||
**Batching:**
|
||||
- Batch API calls (1 request vs 100)
|
||||
- Batch database writes (bulk insert)
|
||||
- Batch file operations (single write vs many)
|
||||
|
||||
**Caching:**
|
||||
- Cache expensive computations
|
||||
- Cache database queries (Redis, in-memory)
|
||||
- Cache API responses (HTTP caching)
|
||||
- Invalidate stale cache entries
|
||||
|
||||
**Async I/O:**
|
||||
- Non-blocking operations (async/await)
|
||||
- Concurrent requests (Promise.all, tokio::spawn)
|
||||
- Connection pooling (reuse connections)
|
||||
|
||||
## Database Optimization
|
||||
|
||||
**Query optimization:**
|
||||
- Add indexes for common queries
|
||||
- Use EXPLAIN/EXPLAIN ANALYZE
|
||||
- Avoid N+1 queries (use joins or batch loading)
|
||||
- Select only needed columns
|
||||
- Filter at database level (WHERE vs client filter)
|
||||
|
||||
**Schema design:**
|
||||
- Normalize to reduce duplication
|
||||
- Denormalize for read-heavy workloads
|
||||
- Partition large tables
|
||||
- Use appropriate data types
|
||||
|
||||
**Connection management:**
|
||||
- Connection pooling (don't create per request)
|
||||
- Prepared statements (avoid SQL parsing)
|
||||
- Transaction batching (reduce round trips)
|
||||
|
||||
</optimization_patterns>
|
||||
|
||||
<workflow>
|
||||
|
||||
Loop: Measure → Profile → Analyze → Optimize → Validate
|
||||
|
||||
1. **Define performance goal** — target metric (e.g., P95 < 100ms)
|
||||
2. **Establish baseline** — measure current performance under realistic load
|
||||
3. **Profile systematically** — identify actual bottleneck (not guesses)
|
||||
4. **Analyze root cause** — understand why code is slow
|
||||
5. **Design optimization** — plan targeted improvement
|
||||
6. **Implement optimization** — make focused change
|
||||
7. **Measure improvement** — verify gains, check for regressions
|
||||
8. **Document results** — record baseline, optimization, gains, tradeoffs
|
||||
|
||||
At each step:
|
||||
- Document measurements with methodology
|
||||
- Note profiling tool output
|
||||
- Track optimization attempts (what worked/failed)
|
||||
- Update performance documentation
|
||||
|
||||
</workflow>
|
||||
|
||||
<validation>
|
||||
|
||||
Before declaring optimization complete:
|
||||
|
||||
**Check gains:**
|
||||
- ✓ Measured improvement meets target?
|
||||
- ✓ Improvement statistically significant?
|
||||
- ✓ Tested under realistic load?
|
||||
- ✓ Multiple runs confirm consistency?
|
||||
|
||||
**Check regressions:**
|
||||
- ✓ No degradation in other metrics?
|
||||
- ✓ Memory usage still acceptable?
|
||||
- ✓ Code complexity still manageable?
|
||||
- ✓ Tests still pass?
|
||||
|
||||
**Check documentation:**
|
||||
- ✓ Baseline measurements recorded?
|
||||
- ✓ Optimization approach explained?
|
||||
- ✓ Gains quantified with numbers?
|
||||
- ✓ Tradeoffs documented?
|
||||
|
||||
</validation>
|
||||
|
||||
<rules>
|
||||
|
||||
ALWAYS:
|
||||
- Measure before optimizing (baseline)
|
||||
- Profile to find actual bottleneck
|
||||
- Use realistic workload (not toy data)
|
||||
- Measure multiple runs (account for variance)
|
||||
- Document baseline and improvements
|
||||
- Check for regressions in other metrics
|
||||
- Consider readability vs performance tradeoff
|
||||
- Verify statistical significance
|
||||
|
||||
NEVER:
|
||||
- Optimize without measuring first
|
||||
- Guess at bottleneck without profiling
|
||||
- Benchmark with unrealistic data
|
||||
- Trust single-run measurements
|
||||
- Skip documentation of results
|
||||
- Sacrifice correctness for speed
|
||||
- Optimize without clear performance goal
|
||||
- Ignore algorithmic improvements
|
||||
|
||||
</rules>
|
||||
|
||||
<references>
|
||||
|
||||
Methodology:
|
||||
- [benchmarking.md](references/benchmarking.md) — rigorous benchmarking methodology
|
||||
|
||||
Related skills:
|
||||
- codebase-recon — evidence-based investigation (foundation)
|
||||
- debugging — structured bug investigation
|
||||
- typescript-dev — correctness before performance
|
||||
|
||||
</references>
|
||||
@@ -0,0 +1,370 @@
|
||||
# Benchmarking Methodology
|
||||
|
||||
Rigorous performance measurement techniques for reliable optimization decisions.
|
||||
|
||||
## Core Principles
|
||||
|
||||
**Statistical rigor** — account for variance, run multiple iterations, report confidence intervals.
|
||||
|
||||
**Environmental isolation** — eliminate noise from other processes, network, disk I/O.
|
||||
|
||||
**Realistic workload** — use production-representative data, not toy examples.
|
||||
|
||||
**Consistent conditions** — same hardware, OS load, data set across runs.
|
||||
|
||||
## Benchmark Design
|
||||
|
||||
### 1. Define Success Criteria
|
||||
|
||||
**Before benchmarking, specify:**
|
||||
- Target metric (latency, throughput, memory)
|
||||
- Acceptable threshold (e.g., P95 < 100ms)
|
||||
- Minimum improvement to justify change (e.g., 20% faster)
|
||||
|
||||
### 2. Choose Workload
|
||||
|
||||
**Representative data:**
|
||||
- Production dataset sample
|
||||
- Realistic data distribution
|
||||
- Edge cases included
|
||||
- Sufficient size (not trivially small)
|
||||
|
||||
**Load patterns:**
|
||||
- Typical request rate
|
||||
- Burst scenarios
|
||||
- Concurrent users/requests
|
||||
- Data size variations
|
||||
|
||||
### 3. Isolate Environment
|
||||
|
||||
**Eliminate interference:**
|
||||
- Close unnecessary applications
|
||||
- Disable background services
|
||||
- Stop cron jobs during testing
|
||||
- Use dedicated hardware if critical
|
||||
|
||||
**System configuration:**
|
||||
- Document CPU, RAM, OS version
|
||||
- Pin process to specific cores (avoid migration)
|
||||
- Disable CPU frequency scaling
|
||||
- Clear filesystem caches between runs
|
||||
|
||||
### 4. Warm Up
|
||||
|
||||
**JIT compilation:**
|
||||
- Run warm-up iterations before measurement
|
||||
- Allow JIT to optimize hot paths
|
||||
- Discard initial slow runs
|
||||
|
||||
**Caching:**
|
||||
- Decide: cold cache or warm cache testing
|
||||
- Document cache state
|
||||
- Be consistent across runs
|
||||
|
||||
## Statistical Methodology
|
||||
|
||||
### Multiple Runs
|
||||
|
||||
**Never trust single measurement:**
|
||||
- Run at least 10-30 iterations
|
||||
- More iterations for high-variance operations
|
||||
- Discard outliers (carefully, document why)
|
||||
|
||||
### Measure Variance
|
||||
|
||||
**Report distribution, not just mean:**
|
||||
|
||||
```text
|
||||
Operation: parse_json
|
||||
Runs: 50
|
||||
Mean: 42.3ms
|
||||
Median (P50): 41.8ms
|
||||
P95: 48.2ms
|
||||
P99: 52.1ms
|
||||
Std Dev: 3.2ms
|
||||
Range: 38.1ms - 54.3ms
|
||||
```
|
||||
|
||||
### Statistical Significance
|
||||
|
||||
**Use t-test or Mann-Whitney U test:**
|
||||
- Null hypothesis: no difference between implementations
|
||||
- Reject if p-value < 0.05 (95% confidence)
|
||||
- Higher confidence (p < 0.01) for critical changes
|
||||
|
||||
**Effect size:**
|
||||
- Report percentage improvement: `(old - new) / old * 100%`
|
||||
- Cohen's d for standardized effect size
|
||||
- Confidence interval around improvement estimate
|
||||
|
||||
## Tool Selection
|
||||
|
||||
### TypeScript/Bun
|
||||
|
||||
**microbench (recommended):**
|
||||
|
||||
```typescript
|
||||
import { bench, run } from 'mitata'
|
||||
|
||||
bench('fast implementation', () => {
|
||||
// code to benchmark
|
||||
})
|
||||
|
||||
bench('slow implementation', () => {
|
||||
// code to benchmark
|
||||
})
|
||||
|
||||
await run()
|
||||
```
|
||||
|
||||
**Benchmark.js:**
|
||||
|
||||
```typescript
|
||||
import Benchmark from 'benchmark'
|
||||
|
||||
const suite = new Benchmark.Suite()
|
||||
|
||||
suite
|
||||
.add('implementation A', () => { /* code */ })
|
||||
.add('implementation B', () => { /* code */ })
|
||||
.on('cycle', (event) => console.log(String(event.target)))
|
||||
.on('complete', function() {
|
||||
console.log('Fastest is ' + this.filter('fastest').map('name'))
|
||||
})
|
||||
.run({ async: true })
|
||||
```
|
||||
|
||||
### Rust
|
||||
|
||||
**criterion (recommended):**
|
||||
|
||||
```rust
|
||||
use criterion::{black_box, criterion_group, criterion_main, Criterion, BenchmarkId};
|
||||
|
||||
fn benchmark_implementations(c: &mut Criterion) {
|
||||
let mut group = c.benchmark_group("comparison");
|
||||
|
||||
for size in [10, 100, 1000].iter() {
|
||||
group.bench_with_input(BenchmarkId::new("fast", size), size, |b, &size| {
|
||||
b.iter(|| fast_implementation(black_box(size)));
|
||||
});
|
||||
|
||||
group.bench_with_input(BenchmarkId::new("slow", size), size, |b, &size| {
|
||||
b.iter(|| slow_implementation(black_box(size)));
|
||||
});
|
||||
}
|
||||
|
||||
group.finish();
|
||||
}
|
||||
|
||||
criterion_group!(benches, benchmark_implementations);
|
||||
criterion_main!(benches);
|
||||
```
|
||||
|
||||
**cargo bench output:**
|
||||
- Automatic outlier detection
|
||||
- Statistical analysis included
|
||||
- Regression detection across runs
|
||||
- HTML reports with plots
|
||||
|
||||
## Comparison Techniques
|
||||
|
||||
### Before/After Comparison
|
||||
|
||||
**Document baseline:**
|
||||
|
||||
```text
|
||||
Baseline (commit abc123):
|
||||
Operation: process_batch
|
||||
Mean: 125ms
|
||||
P95: 142ms
|
||||
Throughput: 8000 ops/sec
|
||||
```
|
||||
|
||||
**Measure improvement:**
|
||||
|
||||
```text
|
||||
Optimized (commit def456):
|
||||
Operation: process_batch
|
||||
Mean: 78ms (-37.6%)
|
||||
P95: 89ms (-37.3%)
|
||||
Throughput: 12800 ops/sec (+60%)
|
||||
|
||||
Statistical significance: p < 0.001
|
||||
```
|
||||
|
||||
### A/B Comparison
|
||||
|
||||
**Concurrent testing:**
|
||||
- Run both implementations with same data
|
||||
- Randomize order to avoid bias
|
||||
- Use same hardware/environment
|
||||
- Report relative performance
|
||||
|
||||
**Example output:**
|
||||
|
||||
```text
|
||||
Implementation A vs B (1000 runs each):
|
||||
|
||||
A: 42.3ms ± 3.2ms
|
||||
B: 38.1ms ± 2.8ms
|
||||
|
||||
Improvement: 9.9% faster (p < 0.01)
|
||||
Effect size: Cohen's d = 1.42 (large)
|
||||
```
|
||||
|
||||
### Scaling Analysis
|
||||
|
||||
**Test multiple input sizes:**
|
||||
|
||||
```text
|
||||
Input Size | Time (ms) | Ops/sec
|
||||
-----------|-----------|--------
|
||||
10 | 1.2 | 8333
|
||||
100 | 11.5 | 869
|
||||
1000 | 118.3 | 85
|
||||
10000 | 1205.7 | 8.3
|
||||
|
||||
Complexity: O(n) confirmed
|
||||
Slope: 0.12ms per item
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Dead Code Elimination
|
||||
|
||||
**Optimizer removes unused results:**
|
||||
|
||||
```typescript
|
||||
// Bad: result never used, might be optimized away
|
||||
bench('compute', () => {
|
||||
compute_expensive()
|
||||
})
|
||||
|
||||
// Good: use black_box or assert result
|
||||
bench('compute', () => {
|
||||
const result = compute_expensive()
|
||||
assert(result !== undefined) // forces computation
|
||||
})
|
||||
```
|
||||
|
||||
```rust
|
||||
// Bad: optimizer removes unused work
|
||||
b.iter(|| expensive_function());
|
||||
|
||||
// Good: black_box prevents elimination
|
||||
b.iter(|| black_box(expensive_function()));
|
||||
```
|
||||
|
||||
### Memory Effects
|
||||
|
||||
**Cache effects distort results:**
|
||||
- Small dataset fits in L1 cache (unrealistic)
|
||||
- Repeated access to same data (cache hot)
|
||||
- Sequential access vs random (cache friendly)
|
||||
|
||||
**Mitigation:**
|
||||
- Use realistic data sizes
|
||||
- Randomize access patterns
|
||||
- Clear caches between runs
|
||||
- Test with cold cache scenario
|
||||
|
||||
### Timing Overhead
|
||||
|
||||
**Measurement affects result:**
|
||||
- Timer resolution too coarse (use nanoseconds)
|
||||
- Timer overhead significant for fast operations
|
||||
- Loop overhead in benchmark
|
||||
|
||||
**Mitigation:**
|
||||
- Batch operations for fast functions
|
||||
- Subtract timer overhead from results
|
||||
- Use high-resolution timers
|
||||
|
||||
### Confirmation Bias
|
||||
|
||||
**Expecting improvement, find it:**
|
||||
- Cherry-picking favorable runs
|
||||
- Ignoring variance in results
|
||||
- Stopping when desired result appears
|
||||
|
||||
**Mitigation:**
|
||||
- Pre-register hypothesis and methodology
|
||||
- Use automated statistical tests
|
||||
- Report all results, not just favorable
|
||||
- Peer review benchmark design
|
||||
|
||||
## Documentation Template
|
||||
|
||||
```markdown
|
||||
## Performance Benchmark: {OPERATION}
|
||||
|
||||
### Goal
|
||||
{PERFORMANCE_GOAL}
|
||||
|
||||
### Environment
|
||||
- Hardware: {CPU, RAM, DISK}
|
||||
- OS: {VERSION}
|
||||
- Runtime: {LANGUAGE_VERSION}
|
||||
- Date: {YYYY-MM-DD}
|
||||
|
||||
### Methodology
|
||||
- Workload: {DESCRIPTION}
|
||||
- Data size: {SIZE}
|
||||
- Iterations: {N}
|
||||
- Warm-up: {N} iterations
|
||||
- Cache state: {COLD/WARM}
|
||||
|
||||
### Baseline (commit {SHA})
|
||||
```text
|
||||
Mean: {X}ms
|
||||
Median: {X}ms
|
||||
P95: {X}ms
|
||||
P99: {X}ms
|
||||
Std: {X}ms
|
||||
```
|
||||
|
||||
### Optimized (commit {SHA})
|
||||
|
||||
```text
|
||||
Mean: {X}ms (-{X}%)
|
||||
Median: {X}ms (-{X}%)
|
||||
P95: {X}ms (-{X}%)
|
||||
P99: {X}ms (-{X}%)
|
||||
Std: {X}ms
|
||||
```
|
||||
|
||||
### Statistical Analysis
|
||||
|
||||
- t-test: p < {VALUE}
|
||||
- Effect size: {COHENS_D}
|
||||
- Conclusion: {SIGNIFICANT/NOT_SIGNIFICANT}
|
||||
|
||||
### Tradeoffs
|
||||
|
||||
- {TRADEOFF_1}
|
||||
- {TRADEOFF_2}
|
||||
|
||||
### Recommendation
|
||||
|
||||
{ACCEPT/REJECT} optimization based on {CRITERIA}
|
||||
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
**Papers:**
|
||||
- "Statistically Rigorous Java Performance Evaluation" (Georges et al.)
|
||||
- "Producing Wrong Data Without Doing Anything Obviously Wrong!" (Mytkowicz et al.)
|
||||
|
||||
**Tools:**
|
||||
- Criterion (Rust) — statistical benchmarking
|
||||
- mitata (JavaScript) — modern benchmarking
|
||||
- perf (Linux) — low-level profiling
|
||||
- Flamegraph — visualization
|
||||
|
||||
**Validation:**
|
||||
- Always review benchmark methodology with team
|
||||
- Reproduce results on different hardware
|
||||
- Document assumptions and limitations
|
||||
- Update benchmarks as codebase evolves
|
||||
Reference in New Issue
Block a user