eaglesakuraの技術ブログ

技術的な話題とか、メモとか。

Androidアプリビルドの並列最大化の限界値

ビルド速度に影響する要素

  • CPU論理コア数
  • シングルコアスペック
  • メモリ
  • プロジェクト自体の並列性

gradleのworker設定

  • gradleには --max-workers 設定がある
  • このオプションを闇雲に指定しても意味はない
  • デフォルト値はCPU論理プロセッサー
    public DefaultParallelismConfiguration() {
        maxWorkerCount = Runtime.getRuntime().availableProcessors();
    }

Workerが増える条件

  • 並列可能なタスクが発生すると、Workerが増える
  • Workerは予約されない。なので、 --max-workersオプションをいくら設定しても、不必要なworkerは起動しない
  • mavenのライブラリ取得とか、並列実行しやすいタスクが発生すると一気に増えるのが観測できる
    • ローカルキャッシュを全消しして、--max-workersをやたら増やすと壮観な図を観れる
   // DefaultBuildOperationQueue
    @Override
    public void add(final T operation) {
        lock.lock();
        try {
            if (queueState == QueueState.Done) {
                throw new IllegalStateException("BuildOperationQueue cannot be reused once it has completed.");
            }
            if (queueState == QueueState.Cancelled) {
                return;
            }
            workQueue.add(operation);
            pendingOperations++;
            workAvailable.signalAll();
            if (workerCount == 0 || workerCount < workerLeases.getMaxWorkerCount() - 1) {
                // `getMaxWorkerCount() - 1` because main thread executes work as well. See https://github.com/gradle/gradle/issues/3273
                // TODO This could be more efficient, so that we only start a worker when there are none idle _and_ there is a worker lease available
                executor.execute(new WorkerRunnable());
            }
        } finally {
            lock.unlock();
        }
    }

最終的に収束するWorker数

  • どんなに頑張っても、module同士の依存によって増えるworker数には限度がある
  • その状態ではCPUコア数よりもシングルスレッド性能のほうが重要となる

  • これらのビルド速度は最終的にほぼ同一に落ち着いた

快適性

  • ビルド速度は同一だが、快適性とは別問題
  • 次のマシンは何にするか