Bazel ユーザーなら誰でも、ビルドが遅い、または想定よりも遅いという経験があるでしょう。個々のビルドのパフォーマンスを改善することは、次のような大きな影響を与えるターゲットにとって特に価値があります。
頻繁に反復処理され、(再)ビルドされるコア デベロッパー ターゲット。
他のターゲットから広く依存されている共通ライブラリ。
ターゲットのクラス(カスタムルールなど)の代表的なターゲット。1 つのビルドで問題を診断して修正すると、大規模な問題の解決に役立つことがあります。
ビルドのパフォーマンスを改善するための重要なステップは、リソースがどこで消費されているかを把握することです。このページでは、収集できるさまざまな指標について説明します。 ビルドのパフォーマンスを分析することで、これらの指標を使用してビルドのパフォーマンスの問題を検出して修正する方法を確認できます。
Bazel ビルドから指標を抽出する主な方法は次のとおりです。
Build Event Protocol(BEP)
Bazel は、Build Event Protocol(BEP)を介してさまざまなプロトコル バッファ
build_event_stream.proto
を出力します。これは、指定したバックエンドで集計できます。ユースケースに応じて、さまざまな方法で指標を集計できますが、ここでは、一般的に考慮すると役立つ概念と proto フィールドについて説明します。
Bazel の query / cquery / aquery コマンド
Bazel には、ターゲット グラフ、構成済みターゲットグラフ、アクショングラフをそれぞれクエリできる 3 つのクエリモード (query、 cquery、 aquery)が用意されています。クエリ言語には、さまざまなクエリモードで使用できる一連の関数が用意されており、ニーズに合わせてクエリをカスタマイズできます。
JSON トレース プロファイル
ビルドのような Bazel の呼び出しごとに、Bazel は JSON 形式でトレース プロファイルを書き込みます。JSON トレース プロファイルは、呼び出し中に Bazel が時間を費やした内容をすばやく把握するのに非常に役立ちます。
実行ログ
実行ログは、マシンと環境
の違いや非決定論的なアクションが原因でリモート キャッシュ ヒットが欠落している場合の
トラブルシューティングと修正に役立ちます。
--experimental_execution_log_spawn_metrics
フラグ(Bazel 5.2 以降で使用可能)を渡すと、ローカルとリモートで実行されたアクションの両方について、詳細な spawn 指標も含まれます。たとえば、これらの指標を使用して、ローカル マシンとリモート マシンのパフォーマンスを比較したり、spawn 実行のどの部分が常に想定よりも遅いか(キューイングなど)を調べたりできます。
実行グラフログ
JSON トレース プロファイルにはクリティカル パスの情報が含まれていますが、実行されたアクションの依存関係グラフに関する追加情報が必要になることがあります。
Bazel 6.0 以降では、フラグ
--experimental_execution_graph_logと
--experimental_execution_graph_log_dep_type=allを渡して、
実行されたアクションとその相互依存関係に関するログを書き出すことができます。
この情報は、クリティカル パス上のノードによって追加される遅延を把握するために使用できます。遅延とは、実行グラフから特定のノードを削除することで節約できる可能性のある時間です。
このデータは、ビルドグラフとアクショングラフに変更を加える前に、その影響を予測するのに役立ちます。
bazel-bench を使用したベンチマーク
Bazel bench は、Git プロジェクトのベンチマーク ツールで、次の場合にビルドのパフォーマンスをベンチマークします。
プロジェクトのベンチマーク: 単一の Bazel バージョンで 2 つの Git コミットを相互にベンチマークします。ビルドの回帰(依存関係の追加によるものが多い)を検出するために使用されます。
Bazel のベンチマーク: 単一の Git コミットで 2 つのバージョンの Bazel を相互にベンチマークします。Bazel 自体の回帰を検出するために使用されます(Bazel を維持またはフォークする場合)。
ベンチマークでは、実経過時間、CPU 時間、システム時間、Bazel の保持ヒープサイズがモニタリングされます。
変動要因を減らすため、他のプロセスを実行していない専用の物理マシンで Bazel bench を実行することをおすすめします。