ベースラインプロファイルでパフォーマンスが改善される仕組みについてまとめた。
導入については下記参照。
Androidのコンパイルと実行
- Androidのソースコードはビルドプロセスの中でコンパイルされ、中間言語であるDexに変換される。
- DexはAABに格納されPlayConsoleへアップロードされる。
- PlayStoreはAABを元に各デバイスの構成に最適化したapkファイルを生成し配信する。
- デバイス上ではapkファイルに含まれたDexのコードをアプリ実行時に機械語へコンパイルして処理を行う。
ベースラインプロファイル
ベースラインプロファイルとは、ソースコードの中で頻繁に実行されるクラスやメソッドのリストをまとめたもの。
Androidデバイスはベースラインプロファイルを元に頻繫に実行されるコードを事前(AOT)コンパイルすることで起動や実行時の処理を高速化することができる。(機械語へコンパイルするプロセスが短縮される)
事前コンパイルはアプリインストール時に行われる。
ベースラインプロファイルの生成
ベースラインプロファイルの生成をするにはMacrobenchmarkライブラリを使用してユーザーが実際に行うクリックやスクロールなどの操作をコードで記述する。
// 参考: https://developer.android.com/topic/performance/baselineprofiles/overview?hl=ja#example
@OptIn(ExperimentalBaselineProfilesApi::class)
class BaselineProfileGenerator {
@get:Rule
val baselineProfileRule = BaselineProfileRule()
@Test
fun appStartupAndUserJourneys() {
baselineProfileRule.collect(packageName = PACKAGE_NAME) {
// App startup journey.
startActivityAndWait()
device.findObject(By.text("COMPOSE LAZYLIST")).clickAndWait(Until.newWindow(), 1_000)
device.findObject(By.res("myLazyColumn")).also {
it.fling(Direction.DOWN)
it.fling(Direction.UP)
}
device.pressBack()
}
}
Macrobenchmarkによるベンチマークの結果をもとに、頻繫に利用されてパフォーマンスに影響を与えるクラスやメソッドを特定し、ベースラインプロファイルが作成される。
クラウドプロファイル
GooglePlayが提供する機能で、ユーザーの実際のアプリ使用データに基づいてプロファイルを生成するというもの。ベースラインプロファイルと同様に、利用頻度の高いクラスやメソッドの情報が含まれており、それを元に事前コンパイルを行うことができる。
ベースラインプロファイルと違う点として、開発者はプロファイルを生成する必要はなく、GooglePlayが定期的にデータを更新し、ユーザーの操作に基づいて最適化プロファイルを更新してくれる。
クラウドプロファイルのデメリットとしては、リリースやアップデート直後はデータが集まっていないので事前コンパイルによるパフォーマンス改善が期待できない点がある。その間はベースラインプロファイルによる最適化によってパフォーマンス改善を行う必要がある。
全てのコードを事前(AOT)コンパイルしない理由
Android5~6ではアプリケーションのコードをインストール時にコンパイルする方式(AOT)だったが、現在では事前(AOT)コンパイルと実行時(JIT)コンパイルのハイブリッド方式になっている。
その理由としては、インストール時間の増加や、ストレージ、メモリ使用量の増加、実行時の最適化ができない問題などがあったよう。