はじめに
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
ファイルは、下記のいずれかの場所に置くことでビルド時に読み込まれます。
- Gradle プロジェクトのトップディレクトリ
$USER_HOME/.gradle/gradle.properties
$GRADLE_USER_HOME/gradle.properties
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 を利用するよう設定されています。
理由については、下記のエントリが紹介されています。
- Android Studio – Migration from Maven Central to JCenter | Blog @Bintray
- Issue 72061 - android - The Maven index is huge! - Android Open Source Project - Issue Tracker - Google Project Hosting
- Feel secure with SSL? Think again. | Blog @Bintray
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を対象にビルド所要時間を測定してみましたが、やはりビルドで一番時間がかかるのはテスト実行のため、ほぼ高速化を体感できませんでした。 ただし、並列ビルドについてはサブプロジェクトのテストが並列に実行されるため、とても効果がありました。