反復処理の速度の最適化

問題を報告 ソースを表示

このページでは、Bazel を繰り返し実行する際に、Bazel のビルド パフォーマンスを最適化する方法について説明します。

Bazel のランタイム状態

Bazel の呼び出しには、複数の相互作用要素が含まれます。

  • bazel コマンドライン インターフェース(CLI)はユーザー向けのフロントエンド ツールであり、ユーザーからコマンドを受け取ります。

  • CLI ツールは、個別の出力ベースごとに Bazel サーバーを起動します。通常、Bazel サーバーは永続的ですが、リソースを浪費しないように、アイドル状態になるとシャットダウンされます。

  • Bazel サーバーは、指定されたコマンド(buildruncquery など)に対して読み込みと分析のステップを実行し、ビルドグラフの必要な部分をメモリ内に構築します。結果として得られるデータ構造は、分析キャッシュの一部として Bazel サーバーに保持されます。

  • Bazel サーバーは、アクション実行を実行することも、リモート実行用にアクションを送信することもできます(設定されている場合)。アクション実行の結果はアクション キャッシュ(またはローカルまたはリモートの実行キャッシュ。ローカルかリモートのどちらかで、Bazel サーバー間で共有される場合があります)にキャッシュされます。

  • Bazel 呼び出しの結果は出力ツリーで確認できます。

Bazel の反復実行

一般的なデベロッパー ワークフローでは、(コンパイル エラーの解決や失敗したテストの調査などのために)コードを非常に高い頻度で繰り返しビルド(または実行)するのが一般的です。この場合、bazel の繰り返し呼び出しのオーバーヘッドを、基盤となる繰り返しアクション(コンパイラの呼び出しやテストの実行など)と比較してできる限り少なくすることが重要です。

このことを念頭に置いて、Bazel のランタイム状態をもう一度見てみましょう。

分析キャッシュはデータの重要な要素です。コールドランの読み込みと分析のフェーズ(Bazel サーバーが起動した直後や分析キャッシュが破棄された直後)だけに、多くの時間が費やされる可能性があります。単一の成功したコールドビルド(製品版リリースなど)の場合、このコストは許容範囲内ですが、同じターゲットを繰り返しビルドするには、このコストを平均化し、呼び出しのたびに繰り返さないことが重要です。

分析キャッシュは比較的揮発性です。まず、Bazel サーバーのインプロセス状態の一部であるため、サーバーを失うとキャッシュも失われます。ただし、キャッシュは簡単に無効化されます。たとえば、bazel コマンドライン フラグの多くは、キャッシュが破棄される原因となります。これは、多くのフラグがビルドグラフに影響するためです(構成可能な属性など)。一部のフラグの変更(起動オプションの変更など)によって、Bazel サーバーが再起動されることもあります。

適切な実行キャッシュは、ビルドのパフォーマンス向上にもつながります。実行キャッシュは、ディスク上またはリモートでローカルに保持できます。キャッシュは Bazel サーバー間でもデベロッパー間でも共有できます。

分析キャッシュの破棄を回避する

分析キャッシュが破棄された場合、またはサーバーが再起動された場合、Bazel は警告を出力します。反復的な使用では、次のいずれかを避ける必要があります。

  • 反復ワークフローの途中で bazel フラグを変更しないように注意してください。たとえば、bazel build -c optbazel cquery を混在させると、各コマンドでもう一方の分析キャッシュが破棄されます。一般に、特定のワークフローの期間中は固定のフラグセットを使用します。

  • Bazel サーバーを失うと、分析キャッシュも失われます。Bazel サーバーには、構成可能なアイドル時間があり、その後シャットダウンします。この時間は、必要に応じて bazelrc ファイルを使用して構成できます。起動フラグが変更されるとサーバーも再起動されるため、可能であればこれらのフラグの変更は避けてください。

  • Bazel の実行中に Ctrl+C を繰り返し押すと、Bazel サーバーが強制終了されます。実行中のビルドが不要になった場合は中断して時間を節約したくなるかもしれませんが、Ctrl+C を 1 回だけ押して現在の呼び出しの正常終了をリクエストします。

  • 同じワークスペースから複数のフラグセットを使用する場合は、複数の異なる出力ベースを --output_base フラグで切り替えて使用できます。各出力ベースは独自の Bazel サーバーを取得します。