mcpField
L
ln-811-performance-profiler

ln-811-performance-profiler

github.com/levnikolaevich開発584184 回インストール2 日前に更新
リポジトリ

ln-811-performance-profiler について

ln-811-performance-profilerは、ファイル、エンドポイント、パイプラインの遅さを調べる開発者向けのプロファイリングスキルです。実行時の複数指標と関数単位のデータから、構造化された性能マップとボトルネックレポートを作成します。

主な機能

  1. 01複数指標の実行時測定
  2. 02関数単位のプロファイリングと計測
  3. 03テストの検出またはベンチマーク作成
  4. 04ボトルネック分類と性能マップ

活用シーン

  1. 01CPU、メモリ、I/O、時間のボトルネック特定
  2. 02エンドポイントや処理パイプラインの分析
  3. 03最適化前の性能ベースライン作成

インストール

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

$npx skills add https://github.com/levnikolaevich/claude-code-skills --skill ln-811-performance-profiler

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

同梱ファイル

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

references/
benchmark_generation.md
bottleneck_classification.md
ci_tool_detection.md
coordinator_summary_contract.md
latency_estimation.md
monitor_integration_pattern.md
output_normalization.md

詳細

パス: ファイルパス(references/、../ln-*)は、このスキルディレクトリを基準とします。

ln-811-performance-profiler

タイプ: L3 ワーカー カテゴリ: 8XX 最適化

最適化対象を実行し、複数の指標(CPU、メモリ、I/O、時間)を計測し、関数単位の内訳を把握できるようコードを計測し、実データに基づいた標準化済みパフォーマンスマップを生成するランタイムプロファイラーです。


概要

項目詳細
入力問題の説明:対象(ファイル/エンドポイント/パイプライン)+観測された指標
出力パフォーマンスマップ(複数指標、関数単位)、疑わしい箇所のスタック、ボトルネックの分類
パターンテストの検出 → ベースライン実行 → 静的解析 → 詳細プロファイル → パフォーマンスマップ → レポート

ワークフロー

フェーズ: テストの検出 → ベースライン実行 → 静的解析 → 詳細プロファイル → パフォーマンスマップ → レポート


フェーズ 0:テストの検出/作成

必ず読み込む: テストフレームワークの検出には references/ci_tool_detection.md を読み込みます。 必ず読み込む: テストが存在しない場合にベンチマークを自動生成するには references/benchmark_generation.md を読み込みます。

最適化対象を実行するコマンドを検出するか、作成します。出力は 2 つです。test_command(プロファイリング/計測用)と e2e_test_command(機能上の安全性を確認するゲート用)です。

ステップ 1:test_command を検出する
優先度方法アクション
1ユーザー指定ユーザーがテストコマンドまたは API エンドポイントを指定します
2既存の E2E テストを検出テストファイルから対象のエントリーポイントを検索します(最初に一致した時点で終了)
3テストスクリプトを作成references/benchmark_generation.md に従って .hex-skills/optimization/{slug}/profile_test.sh を生成します

E2E の検出手順(最初に一致した時点で終了):

優先度方法手順
1ルートベースの検索e2e/統合テストファイルからエントリーポイントのルートを検索します
2関数ベースの検索エントリーポイントの関数名を検索します
3モジュールベースの検索エントリーポイントのモジュールのインポートを検索します

テストの作成(既存のテストが見つからない場合):

対象の種類生成するスクリプト
API エンドポイントcurl -w "%{time_total}" -o /dev/null -s {endpoint}
関数references/benchmark_generation.md に従った、スタックに固有のベンチマーク
パイプラインテスト入力を使ったパイプライン全体の呼び出し
ステップ 2:e2e_test_command を検出する

test_command が E2E の検出(ステップ 1 の優先度 2)で見つかった場合、e2e_test_command = test_command とします。

それ以外の場合、E2E の検出手順(同じ優先度 3 段階の表)を再度実行し、別の機能安全性テストを探します。

見つからない場合は、e2e_test_command = null とし、次のログを記録します:WARNING: No e2e test covers {entry_point}. Full test suite serves as functional gate.

出力
フィールド説明
test_commandプロファイリング/計測用のコマンド
e2e_test_command機能上の安全性を確認するゲート用のコマンド(test_command と同じ場合や、null の場合があります)
e2e_test_source検出方法:user / route / function / module / none

フェーズ 1:ベースライン実行(複数指標)

システムレベルのプロファイリングを使って test_command を実行します。次の指標を同時に取得します。

指標取得方法タイミング
実時間time ラッパーまたはテストハーネス常に
CPU 時間(user+sys)/usr/bin/time -v または言語プロファイラー常に
メモリのピーク(RSS)/usr/bin/time -v(Max RSS)、tracemalloc または process.memoryUsage()常に
I/O バイト数/usr/bin/time -v または構造化ログI/O が疑われる場合
HTTP の往復回数構造化ログまたはアプリケーションメトリクスからカウント呼び出しグラフにネットワーク I/O がある場合
GPU 使用率nvidia-smi --query-gpuスタックで CUDA/GPU が検出された場合のみ
ベースラインの手順
パラメーター値
実行回数3
指標中央値
ウォームアップ1 回実行し、結果を破棄
出力baseline — 複数指標のスナップショット
プロファイラーの実行を監視する(Claude Code 2.1.98 以降)

必ず読むこと: references/monitor_integration_pattern.md を読み込みます

ベースラインおよび詳細なプロファイルの実行中: Monitor(command="{test_command} 2>&1", timeout_ms=300000, description="profiler run N")

クラッシュや無限ループを即座に検出します。フォールバック:Bash と timeout を使用します。


フェーズ 2:静的解析 → 計測ポイント

必ず読むこと: bottleneck_classification.md を読み込みます

コードから呼び出しチェーンをたどり、疑わしい箇所のスタックを構築します。目的: フェーズ 3 で計測する場所を特定します。

ステップ 1:呼び出しチェーンをたどる

エントリーポイントから開始し、深さ優先でたどります(最大深度 5)。各ステップで、関数本体全体を読みます。

サービスをまたぐトレース: コーディネーターから service_topology を利用でき、あるステップでコードにアクセス可能な別のサービスへ HTTP/gRPC 呼び出しを行う場合:

状況対応
サブモジュール/モノレポ内にコードがあるサービスへの HTTP 呼び出しそのサービスのハンドラーをたどります:ルートを特定 → ハンドラーのコードをトレースします(新しいサービスでは深度を 0 にリセット)
コードにアクセスできないサービスへの HTTP 呼び出しExternal と分類し、レイテンシの推定値を記録します
既知のサービスへの gRPC/メッセージキューHTTP と同様に、コードにアクセスできる場合はハンドラーをたどります

各ステップに service: "{service_name}" を記録し、どのサービスがその処理を担うかを追跡します。performance_map の steps ツリーには複数のサービスを含められます。

深さ優先のルール: 呼び出し先サービスのコードにアクセスできる場合は、必ず内部をプロファイルします。内部をプロファイルせずに、アクセス可能なサービスを「External/低速」と分類してはいけません。「低速」は症状であり、診断ではありません。

各ボトルネックに対する 5 Whys: ボトルネックを報告する前に、「なぜ?」を設定/アーキテクチャレベルに到達するまで繰り返します。

  1. 「何が遅いのか?」→ アライメントサービス(5.9 秒) 2. 「なぜ?」→ 6 組 × 約 1 秒 3. 「なぜ 1 組あたり約 1 秒かかるのか?」→ O(n²) の mwmf 計算 4. 「なぜ O(n²) なのか?」→ ライブラリのデフォルトであり、本番設定ではない 5. 「なぜデフォルトなのか?」→ matching_methods が設定されていない → 根本原因 = 設定
ステップ 2:分類と疑わしい箇所のスキャン

各ステップをタイプ(CPU、I/O-DB、I/O-Network、I/O-File、Architecture、External、Cache)で分類し、パフォーマンス上の懸念をスキャンします。

疑わしい箇所のチェックリスト(最低限であり、これに限定されません):

カテゴリー確認する内容
接続管理リクエストごとにクライアントを作成していませんか?プーリングがありませんか?再利用していませんか?
データフローデータを複数回読み込んでいませんか?過剰に取得していませんか?不要な変換をしていませんか?
非同期パターン非同期コンテキストで同期 I/O を行っていませんか?データ依存関係のない await を逐次実行していませんか?
リソースのライフサイクル接続を閉じていませんか?一時ファイルはありませんか?ループ内でメモリが蓄積していませんか?
設定タイムアウトがハードコードされていませんか?プールサイズがデフォルトのままではありませんか?バッチサイズの設定がありませんか?
冗長な処理複数のレイヤーで同じ検証をしていませんか?同じデータを 2 回読み込んでいませんか?
アーキテクチャループ内に N+1 がありませんか?バッチ API を使っていませんか?キャッシュインフラストラクチャを使っていませんか?並列化できる処理を逐次実行していませんか?
(open)ほかに気づいたことがあれば記録します。チェックリストは調査結果を制限しません
ステップ 2b:疑わしい箇所の重複排除

必ず読むこと: references/output_normalization.md を読み込みます

呼び出しチェーンのすべてのステップについて疑わしい箇所を抽出した後、§1~§2 に従って正規化し、重複を排除します。

  • 疑わしい箇所の説明を正規化します(具体的な値をプレースホルダーに置き換えます)
  • 異なるステップにある同一の疑わしい箇所をまとめ、affected_steps: [list] を持つ 1 つの項目に統合します
  • 例:「接続プーリングがない」がステップ 1.1、1.2、1.3 で見つかった場合、affected_steps: ["1.1", "1.2", "1.3"] を持つ 1 つの疑わしい箇所にまとめます
ステップ 3:検証して計測ポイントに対応付ける
FOR each suspicion:
  1. VERIFY: follow code to confirm or dismiss
  2. VERDICT: CONFIRMED → map to instrumentation point | DISMISSED → log reason
  3. For each CONFIRMED suspicion, identify:
     - function to wrap with timing
     - I/O call to count
     - memory allocation to track
プロファイラーの選択(スタックごと)
スタック非侵襲的なプロファイラー侵襲的(非侵襲的な方法で不十分な場合)
Pythonpy-spy、cProfiletime.perf_counter() デコレーター
Node.jsclinic、--profconsole.time() ラッパー
Gopprof(組み込み)通常は不要
.NETdotnet-traceStopwatch ラッパー
Rustcargo flamegraphstd::time::Instant

スタック検出: references/ci_tool_detection.md に従ってください。


フェーズ 3:詳細なプロファイリング

プロファイラーの階層(必要に応じて段階的にエスカレーション)
レベルツールの例表示される内容使用するタイミング
1py-spy、cProfile、pprof、dotnet-trace関数レベルのホットスポット常に — 最初に実施
2line_profiler、行ごとの計測ホットスポット関数内の行ごとの計測時間ホットスポット関数は見つかったが、原因が不明
3tracemalloc、memory_profiler行ごとのメモリ割り当てベースラインのメモリ指標に異常がある
ステップ 1:非侵襲的なプロファイリング(推奨)

コードを変更せずに関数ごとの内訳を取得するため、レベル 1 のプロファイラーを使って test_command を実行します。

ステップ 2:エスカレーションの判断

レベル 1 のプロファイラーを実行した後、結果をフェーズ 2 の疑いのあるスタックと照らし合わせて評価します。

プロファイラーの結果対応
ホットスポット関数が特定され、時間の内訳が疑いを裏付けている完了 — フェーズ 4 に進みます
ホットスポットは特定されたが、内部の原因が不明(1 つの関数内で CPU か I/O かが不明)レベル 2(行ごとの計測)にエスカレーションします
メモリのベースラインに異常がある(ピーク値または差分)レベル 3(メモリプロファイラー)にエスカレーションします
複数の疑いが解消されず、プロファイラーの粒度では不十分ステップ 3(対象を絞った計測)に進みます
プロファイラーを利用できない、またはオーバーヘッドが実時間の 20% を超えるステップ 3(対象を絞った計測)に進みます
停止条件(プロファイラーのエスカレーション)
条件対応
原因が明確なホットスポットを特定できた停止 — パフォーマンスマップに進みます
3 つすべてのプロファイラーレベルを使い切った停止 — 入手可能な最善のデータからマップを作成します
計測によってテストが失敗する停止 — 計測を元に戻し、非侵襲的なデータのみを使用します
プロファイラーのオーバーヘッドが実時間の 20% を超える停止 — 対象を絞った計測に進みます
ステップ 3:対象を絞った計測(積極的に実施)

フェーズ 2 のステップ 3 で特定した計測ポイントに沿って、呼び出しスタックに計測やログ記録を追加します。

1. FOR each CONFIRMED suspicion without measured data:
     Add timing wrapper around target function/I/O call
     Add counter for I/O round-trips if network/DB suspected
     (cross-service: instrument in the correct service's codebase)
2. Re-run test_command (3 runs, median)
3. Collect per-function measurements from logs
4. Record list of instrumented files (may span multiple services)
計測の種類タイミング例
時間計測ラッパー未解決の疑いがある場合は常に関数呼び出しの前後で time.perf_counter() を使用
I/O 呼び出しカウンターネットワークまたは DB がボトルネックと思われる場合ループ内の HTTP リクエスト、DB クエリを数える
メモリスナップショットメモリの蓄積が疑われる場合前後で tracemalloc.get_traced_memory() を使用

計測はそのまま残してください。 実行担当は、最適化後の関数ごとの比較に計測を再利用し、その後、ストライクの後にクリーンアップします。出力では instrumented_files を報告してください。


フェーズ 4:パフォーマンスマップの作成

標準化された形式です。後続処理で使用するため、.hex-skills/optimization/{slug}/context.md に渡します。

performance_map:
  test_command: "uv run pytest tests/automated/e2e/test_example.py -s"
  baseline:
    wall_time_ms: 7280
    cpu_time_ms: 850
    memory_peak_mb: 256
    memory_delta_mb: 45
    io_read_bytes: 1200000
    io_write_bytes: 500000
    http_round_trips: 13
  steps:                          # service field present only in multi-service topology
    - id: "1"
      function: "process_job"
      location: "app/services/job_processor.py:45"
      service: "api"             # optional — which service owns this step
      wall_time_ms: 7200
      time_share_pct: 99
      type: "function_call"
      children:
        - id: "1.1"
          function: "translate_binary"
          wall_time_ms: 7100
          type: "function_call"
          children:
            - id: "1.1.1"
              function: "tikal_extract"
              service: "tikal"   # cross-service: code traced into submodule
              wall_time_ms: 2800
              type: "http_call"
              http_round_trips: 1
            - id: "1.1.2"
              function: "mt_translate"
              service: "mt-engine"
              wall_time_ms: 3500
              type: "http_call"
              http_round_trips: 13
  bottleneck_classification: "I/O-Network"
  bottleneck_detail: "13 sequential HTTP calls to MT service (3500ms)"
  top_bottlenecks:
    - step: "1.1.2", type: "I/O-Network", share: 48%
    - step: "1.1.1", type: "I/O-Network", share: 38%

フェーズ 5:レポート

レポートの構成
profile_result:
  entry_point_info:
    type: <string>                     # "api_endpoint" | "function" | "pipeline"
    location: <string>                 # file:line
    route: <string|null>               # API route (if endpoint)
    function: <string>                 # Entry point function name
  performance_map: <object>            # Full map from Phase 4
  bottleneck_classification: <string>  # Primary bottleneck type
  bottleneck_detail: <string>          # Human-readable description
  top_bottlenecks:
    - step, type, share, description
  optimization_hints:                  # CONFIRMED suspicions only (Phase 2)
    - hint with evidence
  suspicion_stack:                     # Full audit trail (confirmed + dismissed)
    - category: <string>
      location: <string>
      description: <string>
      verdict: <string>               # "confirmed" | "dismissed"
      evidence: <string>
      verification_note: <string>
  e2e_test:
    command: <string|null>             # E2E safety test command (from Phase 0)
    source: <string>                   # user / route / function / module / none
  instrumented_files: [<string>]       # Files with active instrumentation (empty if non-invasive only)
  wrong_tool_indicators: []            # Empty = proceed, non-empty = exit
適切でないツールを示す指標
指標条件
external_service_no_alternative測定時間の 90% 以上を外部サービスが占め、バッチ処理、キャッシュ、並列処理の手段がない
within_industry_norm測定時間が、処理の種類について想定される範囲内
infrastructure_boundボトルネックがハードウェアにある(システム指標で測定)
already_optimizedコードがすでに最適なパターンを使用している(疑いのスキャンで確認済み)

エラー処理

エラー対処
エントリーポイントを解決できないブロック:「{path} にファイル/関数が見つかりません」
変更していないコードでテストコマンドが失敗するブロック:「プロファイリング前にテストが失敗します。まずテストを修正してください」
スタックでプロファイラーを利用できない侵襲的な計測に切り替える(フェーズ 3 ステップ 2)
計測によってテストが失敗する直ちに元に戻す:git checkout -- .
呼び出しチェーンが深すぎる(5 レベル超)深さ 5 で停止し、打ち切りを記録する
ステップの種類を分類できない「不明」を既定値として、実測時間を使用する
I/O が検出されない(CPU のみ)CPU に分類し、アルゴリズムのプロファイリングに注力する

参考資料

  • bottleneck_classification.md — 分類体系
  • latency_estimation.md — レイテンシのヒューリスティック(静的解析のみのモードでのフォールバック)
  • references/ci_tool_detection.md — スタック/ツールの検出
  • references/benchmark_generation.md — スタックごとのベンチマークテンプレート

ランタイム概要アーティファクト

必読: references/coordinator_summary_contract.md を読み込んでください。

optimization-worker のサマリーエンベロープを出力します。

管理モード:

  • ln-810 は決定論的な runId と正確な summaryArtifactPath を渡します
  • 指定された summaryArtifactPath にサマリーを書き込みます

スタンドアロンモード:

  • runId と summaryArtifactPath を省略します
  • .hex-skills/runtime-artifacts/runs/{run_id}/optimization-worker/ln-811--{identifier}.json に書き込みます

完了の定義

  • 最適化対象のテストコマンドを検出または作成している
  • E2E 安全性テストを検出している(または利用できないことを記録している)
  • ベースラインを測定している:実時間、CPU、メモリ(3 回実行、中央値)
  • 呼び出しグラフを追跡し、関数本体を読み込んでいる
  • 疑いのスタックを構築している:各疑いを検証し、計測箇所に対応付けている
  • 詳細なプロファイルを完了している(非侵襲的な方法を優先し、必要に応じて侵襲的な方法を使用)
  • 計測したファイルを報告している(クリーンアップは実行担当者に委ねる)
  • 標準形式でパフォーマンスマップを構築している(実測値を使用)
  • 実測データから上位 3 つのボトルネックを特定している
  • 実際のメトリクスに基づき、誤ったツールの指標を評価している
  • optimization_hints に測定の根拠がある確認済みの疑いのみを含めている
  • 測定結果を含むレポートを作成している
  • 最適化プロファイルのアーティファクトを共有場所に書き込んでいる

バージョン: 3.0.0 最終更新日: 2026-03-15

コメント