mcpField
G
golang-performance

golang-performance

github.com/samber開発3.7k42.4k 回インストール5 日前に更新
リポジトリ

golang-performance について

Go エンジニアやコーディングエージェント向けの、パフォーマンスレビューと最適化のスキルです。まずプロファイルを確認し、変更を一つずつ加えてベンチマークで検証します。

主な機能

  1. 01アーキテクチャとホットパスのレビュー
  2. 02プロファイルに基づくボトルネック診断
  3. 03反復的なベンチマークと比較
  4. 04メモリ、CPU、I/O、ランタイム、キャッシュの指針
  5. 05CIでのベンチマーク回帰チェック

活用シーン

  1. 01Goサービスの構造的な性能問題のレビュー
  2. 02特定済みホット関数の調査
  3. 03benchstatによる最適化効果の検証
  4. 04CIへのベンチマーク回帰チェックの追加

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/samber/cc-skills-golang --skill golang-performance

インストール後、Claude Code で/golang-performanceを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
prometheus-alerts.yml
evals/
evals.json
references/
caching.md
cpu.md
io-networking.md
memory.md
observability.md
runtime.md

詳細

ペルソナ: Go パフォーマンスエンジニアとして行動します。最初にプロファイリングを行わずに最適化することはありません。計測し、仮説を立て、1 つだけ変更し、再計測します。

思考モード: パフォーマンス最適化について、可能な限り徹底的に考察します。浅い分析ではボトルネックを誤認しやすく、深く考えることで、適切な問題に適切な最適化を適用できます。Claude Code では、ultrathink を使って拡張思考を明示的に有効にします。

オーケストレーションモード: Review mode (architecture) で説明されている 3 つのサブエージェント(割り当てとメモリレイアウト、I/O と並行処理、アルゴリズムの計算量とキャッシュ)を並行して実行し、幅広いアーキテクチャのパフォーマンスレビューを行います。単一のホットパスのレビューは逐次的に行います。並行実行が有効なのは、パッケージまたはサービスの範囲に限られます。Claude Code では、ultracode を使って複数エージェントのオーケストレーションを明示的に有効にします。

モード:

  • Review mode (architecture) — パッケージまたはサービスを広く調査し、構造上のアンチパターン(接続プールの不足、上限のないゴルーチン、不適切なデータ構造など)を探します。懸念事項ごとに分けて、最大 3 つのサブエージェントを並行して使用します。(1)割り当てとメモリレイアウト、(2)I/O と並行処理、(3)アルゴリズムの計算量とキャッシュ。
  • Review mode (hot path) — 呼び出し元が指定した単一の関数または密なループを対象に分析します。逐次的に作業し、サブエージェントは 1 つで十分です。
  • Optimize mode — プロファイリングによってボトルネックが特定されています。反復サイクル(メトリクスの定義 → ベースラインの計測 → 原因の診断 → 改善 → 比較)に逐次的に従います。規律として、一度に変更するのは 1 つだけです。

依存関係:

  • benchstat:go install golang.org/x/perf/cmd/benchstat@latest

Go パフォーマンス最適化

基本理念

  1. 最適化の前にプロファイリングする — ボトルネックに関する直感は、約 80% の確率で間違っています。pprof を使って実際のホットスポットを特定してください(→ samber/cc-skills-golang@golang-troubleshooting スキルを参照)
  2. 割り当ての削減が最大の ROI をもたらす — Go の GC は高速ですが、コストがかからないわけではありません。リクエストあたりの割り当てを減らすことは、多くの場合、CPU のマイクロ最適化より重要です。
  3. 最適化を文書化する — パターンが高速である理由を説明するコードコメントを追加し、可能であればベンチマークの数値も記載します。将来の読者が「不要な」最適化を元に戻さないよう、背景情報が必要です。

外部のボトルネックを最初に除外する

Go コードを最適化する前に、ボトルネックが自プロセス内にあることを確認してください。レイテンシの 90% が遅い DB クエリや API 呼び出しによるものなら、割り当てを減らしても効果はありません。

診断: 1- fgprof — CPU 実行時間と CPU 非稼働時間(I/O 待ち)の両方を取得します。CPU 非稼働時間が支配的なら、ボトルネックは外部にあります。2- go tool pprof(ゴルーチンプロファイル)— net.(*conn).Read または database/sql でブロックしているゴルーチンが多数ある場合、外部待ちが発生しています。3- 分散トレーシング(OpenTelemetry)— スパンの内訳から、どの上流サービスが遅いかがわかります。

外部にある場合: そのコンポーネントを最適化します。クエリのチューニング、キャッシュ、接続プール、サーキットブレーカーなどが該当します(→ samber/cc-skills-golang@golang-database スキル、キャッシュパターンを参照)。

反復的な最適化の方法論

サイクル:目標を定義 → ベンチマーク → 診断 → 改善 → ベンチマーク
  1. 指標を定義する — レイテンシ、スループット、メモリ、CPU のどれですか?目標がなければ、最適化は場当たり的になります
  2. アトミックなベンチマークを書く — 結果の混在を避けるため、ベンチマークごとに関数を1つだけ切り分けます(→ samber/cc-skills-golang@golang-benchmark スキルを参照)
  3. ベースラインを測定する — go test -bench=BenchmarkMyFunc -benchmem -count=6 ./pkg/... | tee /tmp/report-1.txt
  4. 診断する — 各詳細セクションの 診断 行を使って、適切なツールを選びます
  5. 改善する — 説明コメントを添えて、一度に1つだけ最適化を適用します
  6. 比較する — benchstat /tmp/report-1.txt /tmp/report-2.txt で統計的有意性を確認します
  7. コミットする — レビュー担当者や将来の読者が改善内容を正確に確認できるよう、コミット本文に benchstat の出力を貼り付けます。コミットタイプは perf(scope): summary に従います
  8. 繰り返す — レポート番号を増やし、次のボトルネックに取り組みます

カスタムの解決策を考案する前に、既知のパターンについてライブラリのドキュメントを参照してください。監査証跡として、すべての /tmp/report-*.txt ファイルを保持してください。

同じボトルネックを複数の最適化候補が競い合う場合は、それぞれを別のサブエージェントを使って、独立したワークツリーで実装してください。次に、バリアントの比較方法と、逐次測定に関する注意事項について、→ samber/cc-skills-golang@golang-benchmark スキルを参照してください(実装を並行してビルドした場合でも、共有 CPU でベンチマークを同時に実行すると測定結果が混在します)。

判断ツリー:時間はどこに使われているか?

ボトルネックシグナル(pprof の結果)対応
割り当てが多すぎるヒーププロファイルで alloc_objects が高いメモリ最適化
CPU バウンドのホットループCPU プロファイルで関数が大部分を占めるCPU 最適化
GC の一時停止/OOMGC% が高い、コンテナの制限ランタイムのチューニング
ネットワーク/I/O のレイテンシI/O でゴルーチンがブロックされているI/O とネットワーキング
高コストな処理の繰り返し同じ計算/取得が複数回行われているキャッシュのパターン
アルゴリズムの誤りO(n) で実行できる処理が O(n²) になっているアルゴリズムの計算量
ロック競合ミューテックス/ブロックプロファイルで負荷が高い→ samber/cc-skills-golang@golang-concurrency スキルを参照
クエリが遅いトレースで DB 処理時間が大部分を占める→ samber/cc-skills-golang@golang-database スキルを参照

よくある誤り

誤り修正方法
プロファイリングせずに最適化するまず pprof でプロファイルを取得します。直感は約80%の確率で間違っています
Transport を設定せずにデフォルトの http.Client を使うMaxIdleConnsPerHost のデフォルト値は2です。同時実行数に合わせて設定します
ホットループ内でログを記録するログ呼び出しはインライン化を妨げ、ログレベルが無効でもメモリを割り当てます。slog.LogAttrs を使います
制御フローに panic/recover を使うpanic はスタックトレースを割り当ててスタックを巻き戻します。エラーを返す方法を使います
ベンチマークで効果を確認せずに unsafe を使う検証済みのホットパスで10%を超える改善がプロファイリングによって確認された場合にのみ正当化されます
コンテナで GC を調整しないOOM による強制終了を防ぐため、GOMEMLIMIT をコンテナメモリの80〜90%に設定します
本番環境で reflect.DeepEqual を使う型付き比較より50〜200倍遅くなります。slices.Equal、maps.Equal、bytes.Equal を使います

詳細解説

CI 回帰検出

CI でベンチマーク比較を自動化し、リグレッションが本番環境に到達する前に検出します。→ benchdiff と cob のセットアップについては、samber/cc-skills-golang@golang-benchmark スキルを参照してください。

相互参照

  • → ベンチマークの手法、benchstat、b.Loop()(Go 1.24+)については、samber/cc-skills-golang@golang-benchmark スキルを参照してください
  • → pprof のワークフロー、エスケープ解析の診断、パフォーマンスのデバッグについては、samber/cc-skills-golang@golang-troubleshooting スキルを参照してください
  • → スライス/マップの事前割り当てと strings.Builder については、samber/cc-skills-golang@golang-data-structures スキルを参照してください
  • → ワーカープール、sync.Pool API、ゴルーチンのライフサイクル、ロック競合については、samber/cc-skills-golang@golang-concurrency スキルを参照してください
  • → ループ内の defer、スライスのバッキング配列のエイリアスについては、samber/cc-skills-golang@golang-safety スキルを参照してください
  • → 接続プールのチューニングとバッチ処理については、samber/cc-skills-golang@golang-database スキルを参照してください
  • → 本番環境での継続的なプロファイリングについては、samber/cc-skills-golang@golang-observability スキルを参照してください

コメント