ユーザーが「ベンチマーク実行」「パフォーマンス測定」「性能分析」「速度を測って」「ベンチマークして」等と要求した時に発動。 Go benchmarkを実行し、結果を分析してボトルネックを特定し、改善提案を行う。 既存のベンチマークがない場合は、まず作成する。
Scanned 2/10/2026
Install via CLI
openskills install majiayu000/claude-skill-registry---
name: benchmark-analyzer
description: >-
ユーザーが「ベンチマーク実行」「パフォーマンス測定」「性能分析」「速度を測って」「ベンチマークして」等と要求した時に発動。
Go benchmarkを実行し、結果を分析してボトルネックを特定し、改善提案を行う。
既存のベンチマークがない場合は、まず作成する。
allowed-tools: Read, Write, Edit, Grep, Glob, Bash
---
### 手順
1. **ベンチマーク対象の特定**:
- ユーザー指定がある場合: その関数
- 指定がない場合: パフォーマンスが重要な関数を検出
2. **既存ベンチマークの確認**:
- `*_test.go` 内の `Benchmark` 関数を検索
- 存在しない場合は、ベンチマーク関数を生成
3. **ベンチマーク実行**:
- `go test -bench=. -benchmem -benchtime=3s` を実行
- 複数回実行して安定した結果を取得
4. **結果の分析**:
- ns/op (1操作あたりのナノ秒)
- B/op (1操作あたりのバイトアロケーション)
- allocs/op (1操作あたりのアロケーション回数)
5. **ボトルネック特定**:
- CPU プロファイリング(必要に応じて)
- メモリプロファイリング(アロケーションが多い場合)
- `go test -bench=. -cpuprofile=cpu.prof`
6. **改善提案**:
- 具体的な最適化案を提示
- トレードオフ(可読性 vs パフォーマンス)を明記
7. **レポート生成**: 結果と提案をマークダウン形式で出力
### ベンチマーク関数の生成例
```go
func BenchmarkSum(b *testing.B) {
nums := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sum(nums)
}
}
func BenchmarkSumLarge(b *testing.B) {
nums := make([]int, 10000)
for i := range nums {
nums[i] = i
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
Sum(nums)
}
}
```
### 分析レポートフォーマット
```markdown
# Benchmark Analysis Report
## Summary
Function: `Sum()`
Date: 2025-10-23
## Benchmark Results
### Small Input (10 elements)
```
BenchmarkSum-8 50000000 25.3 ns/op 0 B/op 0 allocs/op
```
### Large Input (10,000 elements)
```
BenchmarkSumLarge-8 100000 11234 ns/op 0 B/op 0 allocs/op
```
## Analysis
### Performance Characteristics
- ✅ **Good**: Zero allocations - operates on input slice without copying
- ✅ **Good**: Linear time complexity O(n) as expected
- ⚠️ **Note**: Performance scales linearly with input size
### Bottlenecks
None detected. Implementation is optimal for this use case.
## Optimization Opportunities
### 1. SIMD Optimization (Advanced)
For very large slices (>100k elements), could consider SIMD instructions.
**Trade-off**: Significant complexity increase for marginal gains.
**Recommendation**: Not worth it for this use case.
### 2. Parallel Processing
For slices >10M elements, could use goroutines.
```go
func SumParallel(nums []int) int {
// Split into chunks, sum in parallel, combine
}
```
**Trade-off**: Overhead makes it slower for typical use cases.
**Recommendation**: Only if consistently processing huge datasets.
## Comparison with Standard Library
| Implementation | Time (ns/op) | Allocs |
|----------------|--------------|--------|
| Current Sum() | 25.3 | 0 |
| Naive approach | 28.1 | 0 |
Current implementation is 10% faster than naive approach.
## Recommendations
1. ✅ **Keep current implementation** - Already optimized
2. ✅ **Add benchmark to CI** - Detect performance regressions
3. ❌ **Don't optimize further** - Diminishing returns
## Action Items
- [ ] Add benchmarks to test suite
- [ ] Document performance characteristics in GoDoc
```
### パフォーマンス最適化の観点
#### メモリアロケーション削減
- 不要な `append` を避ける
- スライス容量を事前確保(`make([]T, 0, capacity)`)
- `sync.Pool` でオブジェクト再利用
- ポインタ vs 値のトレードオフ
#### CPU最適化
- ループアンローリング(コンパイラが通常やる)
- 分岐予測を意識(ホットパスを最適化)
- インライン化(小さな関数)
- 不要な型変換を避ける
#### プロファイリングコマンド
```bash
# CPU プロファイル
go test -bench=. -cpuprofile=cpu.prof
go tool pprof cpu.prof
# メモリプロファイル
go test -bench=. -memprofile=mem.prof
go tool pprof mem.prof
# トレース
go test -bench=. -trace=trace.out
go tool trace trace.out
```
### ベンチマークのベストプラクティス
- `b.ResetTimer()` で初期化コストを除外
- 複数の入力サイズでテスト(small, medium, large)
- `-benchtime=3s` で安定した結果を取得
- `-count=5` で統計的信頼性を確保
- ベンチマーク専用のデータを使う(本番データは避ける)
### 警告: 早すぎる最適化
- まず正確性、次に可読性、最後にパフォーマンス
- 計測してから最適化(推測しない)
- ボトルネックを特定してから対処
- パフォーマンス改善は具体的な数値で示す
No comments yet. Be the first to comment!