📦 deps(thirdparty): update snapshots

This commit is contained in:
ci[bot]
2026-05-29 08:33:53 +00:00
parent fdb52f1e96
commit 06e0d13d57
1615 changed files with 232858 additions and 0 deletions
@@ -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