OpenClaw パフォーマンス
無駄とは、リクエストが本来必要としない処理のことです。大きな高速化は、同じ処理をより速く行うことからではなく、無駄を削除することから生まれます。キャッシュは最後の手段です。キャッシュは、そのキー、無効化、またはヒット率が破綻するまで無駄を隠蔽し、その後無駄が再発します。
1. 計測
最初の実行 前 に、PR内に合格基準を記述します。フロー、ワークロード、メトリクス、コールドかウォームか、サンプル数、そして勝利または後退とみなす変化を明記します。
| フロー | コミットされたワークロード |
|---|---|
| CLI 起動 | pnpm test:startup:bench(:check が予算を保持) |
| Gateway 起動 / 再起動 | scripts/bench-gateway-startup.ts、scripts/bench-gateway-restart.ts、scripts/perf/post-restart-burst-measure.ts |
| Chat ターン、ターンあたりのフレーム数 | scripts/bench-channel-turn.mts、scripts/perf/transcript-broadcast-measure.ts |
| Control UI コールドロード | scripts/bench-control-ui-cold-load.ts、pnpm ui:check-performance(:base が比較) |
| セッション一覧、マルチエージェント形状 | scripts/perf/team-shape-fixture.ts、src/gateway/session-list-viewers.perf.test.ts |
| 並行性、SQLite 状態 | scripts/bench-gateway-concurrency.ts、pnpm test:sqlite:perf |
- まずカウントする: ウォールタイムの前に、アクションあたりの操作数(SQL文、RPCとフレーム数、ファイル読み取り、カタログまたはレジストリのロード数、スプローン数、レンダリング数)。カウントは負荷の高いホストでも安定します。ゼロであるべきカウントがある場合、それはバグです。
- 実際のフロー: テスト対象のヘッド上の独立したGateway、実際のトランスポート、低速パスも含めて。モックのGateway、古いビルド、または開発サーバーは別のものを計測します。
- サンプル: ベースラインと候補をインターリーブ(ABAB)、各最低5サンプル、コールドとウォームは分離。中央値と95パーセンタイルをばらつきとともに、直列に実行し、ホスト負荷を記録。
- 再実行可能: コミットされたスクリプトのみがカウントされます。適切なスクリプトがない場合は、既存のものを拡張します。
- プロファイル: ホットパス上で、スレッドごとに
node --cpu-prof、またはブラウザのパフォーマンストレース。
コミットされたワークロード、ベースラインテーブル、および記述されたルールが揃った時点で完了です。
2. 無駄を見つける
カウントされたすべての操作について問いかけます:このリクエストはそれを必要としていますか? OpenClaw でよく見られる無駄:
- クリティカルパス上の先取り処理: プラグインローダーをインポートしたレジストリルックアップ(#133518、47.07秒 → 10.36秒)。起動時にオプションのランタイムをロード(#119374)。
- 行ごとまたは呼び出しごとの再計算: アーカイブ行ごとの同期読み取り(#156665、56,700 読み取り → 0)。フレームごとに解決されるログパターン(#150042、10,000 フレームあたり 539 → 17 ms)。
- 承認済み状態の再チェック: ウォームハンドルでのスキーマ、承認、またはフレッシュネスチェック(#166102、#172676。SQLite 承認チェーン内の 14 PR)。
- ストリームされたデルタごとの完全再スキャン: すべてのトークンで応答全体を再処理(#158526、256 KiB で 5,342 → 1 ms CPU)。
- 自身の書き込みの再読み取り: ルックアップあたり 2 回のデータベースバックアップ(#161551、772.8 → 7.7 ms)。Doctor はチェックしたばかりのものを再スキャンしてバックアップした(#174665、約26 → 3.0 秒)。
- 繰り返されるカタログまたはレジストリのビルド: 起動時のエージェントごとのカタログ再ビルド(#116261、24.9 → 5.0 秒)。ミスまたは TTL ごとの再ビルド(#127178、#167008)。
- オプショナルデータの待機: Usage ページはプロバイダープランを待機し、無関係な読み取りをリトライした(#176358)。
- 防御的コピーとラッピング: ターンごとの
structuredClone(#172940、1.685 MiB → 0)。値ごとの境界ラッピング(#163818、11,571 → 500 ns/イベント)。 - 呼び出しごとのスプローンまたはファンアウト: 解決ごとの子プロセス(#155779、100 → 0)。
- レンダリングカスケードと完全ペイロード: 更新ごとのレンダリング(#159400、250 → 79)。1つのデルタのために完全な行を再送信(#165404、21.75 → 0.95 MB)。
支配的な各カウントが、それを発行するコードにトレース可能であり、「必要」かどうかの yes/no がついた時点で完了です。
3. この順序で修正する
- 削除 無駄を。削除はめったに元に戻りません。失敗した削除はガードを取り除いたことを意味するため、契約を保護するすべてのチェックを維持し、契約がまだ有効であることを証明してください。
- 所有者に一度:呼び出し元は、所有者が記録した事実を消費します。
- 準備済みの事実をホットパスに引き継ぐ。
- 独立した作業をバッチ化し、バッチがフレーム、レイテンシテール、コールドスタートを安定に保つことを証明します。結合処理は3回元に戻されました(#162560、#173901、#175092)。
- キャッシュ、手順1〜4が適用できない理由を記述して。ルート「キャッシュの同一性」に従い、所有者の書き込みから無効化し、サイズを制限し、インターリーブされた作業カウントテストを追加します。4つのキャッシュ再修正のうち3つはサイレントミスでした。読者が互いに追い出し合う(#115369 → #174741)、スラッシングする予算(#149773 → #149879)。
ワーカーの移動や遅延はコストを移動させます。メインスレッドと総作業の両方をカウントしてください。
カウントから無駄がなくなった時点、またはPRがどのステップで停止したかとその理由を述べている時点で完了です。
4. ランディング
- ステップ1のワークロードをベースラインと候補で同じルールのもとで再実行します。
- すべてのユーザー向けメトリクスが維持または改善すること:レイテンシ、p95/p99、フレーム数、コールドスタート、CPU、メモリ、カウント。悪化したメトリクスについては、PR内で所有者の明示的な承認が必要です。1つのセルで20%の変動は停止であり、「ばらつきの範囲内」ではありません。元に戻された6つのパフォーマンスPRのうち5つは、そのボディ内で後退を示していました。
- 測定可能な利益のない変更は元に戻します。
- 証拠はPR内にあり、新しいテストではありません。before/afterのカウントが証拠です。この無駄が以前に再発したことがある場合にのみ、フローの既存の作業カウントテストを拡張します。test-audit がテストの価値を管理します。
- PRの証拠:ワークロードコマンド、合格基準、before/afterテーブル(カウントと時間、中央値とp95、サンプル数)、削除された無駄、そして悪い方向に動いたメトリクスがあればそれも。
テーブルがステップ1で記述されたルールを満たした時点で完了です。
関連
テストスイートの速度: openclaw-test-performance。テストのヒープ増加: openclaw-test-heap-leaks。CI容量: openclaw-ci-limits。