おそらく、すべての 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 実行のどの部分が(キューイングなどにより)常に想定よりも遅いかを調べたりできます。
実行グラフログ
JSON トレース プロファイルにはクリティカル パス情報が含まれていますが、実行されるアクションの依存関係グラフで追加情報が必要になることがあります。Bazel 6.0 以降では、フラグ --experimental_execution_graph_log
と --experimental_execution_graph_log_dep_type=all
を渡して、実行されたアクションとその相互依存関係に関するログを書き出すことができます。
この情報を使用して、クリティカル パス上のノードによって追加されるドラッグを理解できます。ドラッグ時間は、実行グラフから特定のノードを削除することで節約できる可能性のある時間です。
このデータは、実際に変更を行う前に、ビルドとアクションのグラフに対する変更の影響を予測するのに役立ちます。
bazel-bench によるベンチマーク
Bazel ベンチは、次のような場合にビルド パフォーマンスをベンチマークする、Git プロジェクトのベンチマーク ツールです。
プロジェクト ベンチマーク: 単一の Bazel バージョンで、2 つの Git commit を相互にベンチマークします。ビルドの回帰を検出するために使用されます(多くの場合、依存関係の追加)。
Bazel ベンチマーク: 1 回の Git commit で 2 つのバージョンの Bazel を相互にベンチマークします。Bazel 自体内の回帰を検出するために使用されます(Bazel のメンテナンスやフォークを行った場合)。
ベンチマークでは、経過時間、CPU 時間、システム時間、Bazel の保持ヒープサイズをモニタリングします。
変動の原因を減らすため、他のプロセスを実行していない専用の物理マシンで Bazel ベンチを実行することもおすすめします。