Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Speeding up your Android Gradle builds

Speeding up your Android Gradle builds

takenach

June 16, 2017
Tweet

More Decks by takenach

Other Decks in Programming

Transcript

  1. Code change impact (before 3.0) • lib2 で コードに変更を加えると、直接参照している lib1

    だけでなく 間接的(推移的)に参照している app も recompile される
  2. Compilation avoidance • ABI (Application Binary Interface) の概念 ◦ ABI

    change ▪ public フィールドやメソッドの追加・削除 ▪ public フィールドやメソッド IF の変更 ▪ 参照モジュールの recompile のトリガーになる ◦ Non ABI change ▪ private ( 外部に影響のない ) 変更 ▪ public メソッドの内部実装の変更 ▪ 参照モジュールを recompile しない
  3. ABI code change impact • lib1, app を recompile する 

    ( ※ ‘compile’ のままだと )
  4. New dependency config in 3.0 • compile is now deprecated

    • Replace with api or implementation dependencies { compile project(':libY') compile project(':libZ') api project(':libY') implementation project(':libZ') }
  5. api vs implementation • api ◦ compile と同等の動作をする ▪ because

    → compile を api に置き換えれば動作はする but → オススメはしない ◦ 参照 モジュールの public API が、自身の API の一部になる場合に使 用
  6. api vs implementation • implementation ◦ 参照 モジュール を公開しない場合 ◦

    自身を参照するモジュールには、 ”implementation” で取り込んだモ ジュールの public API は見えない ◦ Application モジュールは基本的に implementation を使えば良い ▪ テストを別モジュールで構成したりしている場合は api を使わない とならないケースもある
  7. public class LibXLibYWrapper { private final LibYClass1 y1Obj; public LibXLibYWrapper(LibYClass1

    y1Obj) { this.y1Obj = y1Obj; } public void LibXPublic1() { LibYClass2 y2Obj = new LibYClass2(val); int type = LibXPrivate1(y2Obj); LibZExecute(type) ~~~~~ } private int LibXPrivate1(LibYClass2 method) { ~~~~~ } } dependencies { compile project(':libY') compile project(':libZ') api project(':libY') implementation project(':libZ') } Dependencies of LibX LibYのクラスをLibXの public API の一部と して使っている → api で参照する必要がある LibZのメソッドを public API で使っている が、内部でしか使っていない → implementation で参照すれば良い LibX LibY LibZ App
  8. New dependency config in 3.0 New configuration Deprecated configuration Behavior

    implementation compile 前述 api compile 前述 compileOnly provided provided と同等 compile 時にのみ使用する runtimeOnly apk apk と同等 package 時のみ使用する • compile, provided, apk は次のメジャーバージョンアップ( 4.0 ? )で無くなるらしい
  9. Conclusion • Compilation avoidance ◦ ABI change / Non ABI

    change の概念を導入したことによって無駄な recompile が発生しない • api / implementation configurations ◦ api / implementation を使い分けること(極力 implementation で済む ように実装すること)で、無駄な recompile が発生しない ⇒ Faster builds !!
  10. Slow builds are not normal • full build が数分以内に終わらない ◦

    10 分かかったら普通じゃない、らしい • Incremental build が full build と比べてそれほど速くない • 何も変更せずに Incremental build をしても、 up-to-date タスク(実行がス キップされるタスク)がほとんどない
  11. Any Help ? • ./gradlew [ex. assembleDebug] --dry-run ◦ gradle

    タスクの空実行 ◦ 何のタスクがどの順番で実行されているかがわかる ◦ 通常数秒で終わる ◦ これが 10 秒以上かかるような場合は、 plugin などが悪さをしている可能 性がある
  12. Any Help ? • ./gradlew [ex. assembleDebug] --info ◦ 何のタスクがなぜ走っているかを教えてくれる

    ◦ 例えば、何も変更せずに Incremental build をして、なぜタスクがスキッ プされないかをなどがわかる
  13. Any Help ? • ./gradlew [ex. assembleDebug] --profile ◦ 各タスクの実行にどのくらい時間がかかっているかを

    html で出力して くれる ◦ build/reports/profile の中に下記の様な html が出力される ex) profile-2017-06-16-19-30-00.html
  14. Filing performance bugs • gradle-profiler で Yourkit というプロファイラを使ってプロファイルした結果 を提出すれば、なぜ Build

    が遅いのかを調べてくれるらしい ◦ ただし、このセッションで説明したことを全て実践したけど、 まだ遅い、自分で調べてもわからない、という場合に限る! • > gradle-profiler --profile yourkit --yourkit-memory --project-dir . clean assembleDebug みたいな感じで、調査したいタスクに対してプロファイルを実行すると、 『 profile-out-X.log 』が吐き出されるのでそれを送るっぽい。
  15. More Info • Google I/O 2017 Session Movie ◦ https://www.youtube.com/watch?v=7ll-rkLCtyk

    • Optimize your build speed ◦ https://developer.android.com/studio/build/optimize-your-build.html • Migration Guide to Android Gradle plugin 3.0 ◦ https://developer.android.com/studio/preview/features/new-android-plugin-migration.html#apply_p lugin • Gradle profiler ◦ https://github.com/gradle/gradle-profiler • Tips for faster development builds (my slide) ◦ https://goo.gl/7zOH9H