はじめに

Gradle のビルドを高速化する方法について、下記エントリを参考に調べてみました。 10 Tips to Improve Your Gradle Build Time — Medium

記事の冒頭でも書かれている通り、上記のエントリは Android プロジェクト向けに書かれていますが、Android プロジェクトでなくても Gradle プロジェクトならば適用できる方法ばかりです。 (一つ Android 限定のものもありますが) 特にマルチプロジェクト構成の際に効果が高いものばかりなので、大規模な Gradle プロジェクトを構築する際の参考になりそうです。

ただ、最後のまとめにも書きましたが、ビルド時間の大半を占めるのがテスト実行時間であることが多いため、劇的にビルドが早くなるという訳では無いかと思いました。

0. ドキュメント

Gradle のコマンドラインオプションと実行時オプションを利用する方法が多いため、公式ドキュメントを載せておきます。

Appendix D. Gradle Command Line The Build Environment - Gradle User Guide Version 2.14

1. デーモン化

これは昔から推奨されてましたね。 Gradle プロセスを常駐化させることで、JVM の起動や必須ライブラリの読み込みを毎回行わなくて済むようにする方法。

The Gradle Daemon - Gradle User Guide Version 2.14

指定方法

org.gradle.daemon=true

or

./gradlew --daemon # 一度起動するとそのまま常駐します
./gradlew build

2. 並列ビルド (incubating)

マルチプロジェクトビルド限定です。 互いに参照しあっていないプロジェクト(Decoupled Project)のビルドを並列実行できます。

指定方法

org.gradle.parallel=true
org.gradle.workers.max=4  # 並列の最大数(デフォルトではプロセッサの数)

or

./gradlew build --parallel --max-workers=4
./gradlew build --parallel --parallel-threads=4

--max-workers--parallel-threadはどちらもorg.gradle.workers.maxと同じく、並列の最大数を指定するオプションです。 同時に指定された場合、--parallel-threadが優先されるそうです。

3. オンデマンド Configure (incubating)

Multi-project Builds - Gradle User Guide Version 2.14

Gradle ビルドの Configure Phase を必要なときだけ行うということですかね。 ちょっとここらへん理解が浅いです。

指定方法

org.gradle.configureondemand=true

or

./gradlew build --configure-on-demand

4. グローバル設定

今まで紹介した手法と趣向が異なります。

1-3 でも登場したgradle.properteisファイルは、下記のいずれかの場所に置くことでビルド時に読み込まれます。

1-3 に挙げているようなオプションは、プロジェクト関係なく有効な手法なのでユーザ設定にしてしてしまっても良さそうです。

The Build Environment - Gradle User Guide Version 2.14

5. 最小化

ビルド実行時のコマンドラインオプションで実行しないタスクを指定できます。 Using the Gradle Command-Line - Gradle User Guide Version 2.14

指定方法

./gradlew build -x test
./gradlew build --exclude-task test

6. minSdkVersion を設定して ART のみを対象に

Android プロジェクト限定です。 Android SDK の最低バージョンを23に設定することで Dalvik 向けの dexing?をしないようにするみたいです。

Android Studio のドキュメントでも紹介されているやり方のようで。 Configure Apps with Over 64K Methods | Android Studio

指定方法

...

def minSdk = hasProperty('minSdk') ? minSdk : 16

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.2"

    dexOptions {
        javaMaxHeapSize "4g"
        jumboMode true
    }

    defaultConfig {
        applicationid "com.myapplication.app"

        minSdkVersion minSdk
        targetSdkVersion 23
...
./gradlew assembleDebug -PminSdk=23

Android Studio での指定方法については下記を参考に。 How to make faster Android build without sacrificing new api lint check

7. オフライン実行

Gradle がネットワークリソースへアクセスするのを抑止するオプションのようです。 一度、ビルドに必要な資産をダウンロードすれば、以降はオフラインでも良さそう。

指定方法

./gradlew build --offline

8. Gradle のバージョンを 2.4 まで上げる

公式ブログでもアナウンスがあったように、Gradle2.4 では 2.3 の時より configuration time が 34%も削減されているそうで。 Gradle 2.4: The fastest yet - Gradle

現在、Gradle2.14 までリリースされているので、2.3 以下を使っている場合はちょっと古すぎるので上げておくべきかと。

9. jCenter の利用

MavenCentral より jCenter を利用しましょうということらしいです。 確かに Gradle の build-init plugin を使って生成した build.gradle でも、jCenter を利用するよう設定されています。

理由については、下記のエントリが紹介されています。

10. Profile!

ちゃんとプロファイリングして、自分たちのビルドの内容を把握しておこうということですね。 --profileオプションを付けてビルドを実行すると、ビルドプロファイリングの HTML ファイルが出力されます。

Using the Gradle Command-Line - Gradle User Guide Version 2.14

また、Gradle Inc.はGradle Build Scansというサービスを開始しているので、コレを利用するのも良いかもしれません。 このサービスについては、私のブログで少し紹介しています。 Gradle がビルド結果解析サービス Gradle.com を開始していた - kaakaa Blog

指定方法

./gradlew build --profile

さいごに

いくつかの高速化手法について、Netflix/Hystrixを対象にビルド所要時間を測定してみましたが、やはりビルドで一番時間がかかるのはテスト実行のため、ほぼ高速化を体感できませんでした。 ただし、並列ビルドについてはサブプロジェクトのテストが並列に実行されるため、とても効果がありました。

comments powered by Disqus