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