ベースライン プロファイル

ベースライン プロファイルにより、含まれるコードパスの解釈とジャストインタイム(JIT)コンパイルの手順を行う必要がなくなるため、初回起動からのコード実行速度が約 30% 向上します。

ベースライン プロファイルとともにアプリやライブラリをリリースすることで、Android ランタイム(ART)は、事前(AOT)コンパイルによって指定されるコードパスを最適化し、すべての新規ユーザー、すべてのアプリ アップデートでパフォーマンスを向上できます。このプロファイルに基づく最適化(PGO)を使用すると、起動の最適化、インタラクション ジャンクの削減、エンドユーザーの全体的なランタイム パフォーマンスの向上がアプリの初回起動時から可能になります。

こうしたパフォーマンスの向上は、ユーザー維持率、トランザクション、評価などのビジネス指標の改善に直接つながります。パフォーマンスがビジネス指標に及ぼす影響については、JoshLyftTikTokZomato の事例をご覧ください。

ベースライン プロファイルのメリット

ベースライン プロファイルを使用すると、ユーザーの操作(アプリの起動、画面間の移動、コンテンツのスクロールなど)がすべて、初回の実行時からスムーズに行えるようになります。アプリの速度と応答性を高めると、1 日あたりのアクティブ ユーザー数が増加し、平均再利用率が高まります。

ベースライン プロファイルは、アプリの最初の起動からアプリのランタイムを改善する一般的なユーザー インタラクションを提供して、アプリの起動以外も含めて最適化する際の指針となります。指針に沿った AOT コンパイルは、ユーザーのデバイスに依存せず、モバイル デバイスではなく開発マシンでリリースごとに 1 回実行できます。ベースライン プロファイルとともにアプリをリリースすることで、Cloud プロファイルのみを使用する場合よりもはるかに速く、最適化されたアプリを利用できるようになります。

ベースライン プロファイルを使用しない場合は、すべてのアプリコードが解釈後にメモリ内で JIT コンパイルされるか、デバイスがアイドル状態のときにバックグラウンドで odex ファイルに書き込まれます。アプリをインストールまたは更新した後は、初めて実行したときから新しいコードパスが最適化されるまで、最適なパフォーマンスは得られません。最適化後のパフォーマンスは、多くのアプリで 30% 程度改善することがわかっています。

始める

既存のアプリでパフォーマンスを最適化するにあたっては、ベースライン プロファイルの作成をご覧ください。

依存関係チェーンでは、安定版リリース バージョンと開発リリース バージョンが提供されます。ベースライン プロファイルを生成してインストールするには、少なくとも、Android Gradle プラグインの最小サポート バージョン、Macrobenchmark ライブラリ、プロファイル インストーラを使用する必要があります。これらの依存関係は異なるタイミングで必要になり、最適なベースライン プロファイルを実現するツールチェーンとして連携して機能します。

  • Android Gradle プラグイン: com.android.tools.build:8.0.0
  • Macrobenchmark: androidx.benchmark:benchmark-macro-junit4:1.1.1
  • プロファイル インストーラ: androidx.profileinstaller:profileinstaller:1.3.1

プロファイル生成の例

アプリ起動用のベースライン プロファイルに加えて、推奨される Macrobenchmark ライブラリを使用するいくつかのナビゲーション イベントおよびスクロール イベントを作成するクラスの例を以下に示します。

@OptIn(ExperimentalBaselineProfilesApi::class)
class BaselineProfileGenerator {
    @get:Rule
    val baselineProfileRule = BaselineProfileRule()

    @Test
    fun appStartupAndUserJourneys() {
        baselineProfileRule.collectBaselineProfile(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()
        }
    }
}

このコードは GitHub のパフォーマンス サンプルに含まれており、完全なコンテキストおよび詳細情報と合わせて確認できます。

追加すべき要素

アプリでベースライン プロファイルを使用する場合、アプリの起動コードと、画面間のナビゲーションやスクロールなどの一般的なユーザー操作を含めることができます。登録、ログイン、支払いなどのフロー全体を収集することもできます。

ライブラリが提供する独自のベースライン プロファイルをアプリの一部としてリリースすると、アプリのパフォーマンスを改善できます。例については、Compose でベースライン プロファイルを使用するをご覧ください。

ベースライン プロファイルの仕組み

アプリやライブラリの開発でベースライン プロファイルを定義する際は、レンダリング時間やレイテンシが重要となる一般的なユーザー操作がカバーされるようにしてください。 仕組みは次のとおりです。

  1. 人間が判読できる形式でプロファイル ルールがアプリ用に生成され、アプリ内でバイナリ形式にコンパイルされます(assets/dexopt/baseline.prof にあります)。その後、AAB を通常どおり Google Play にアップロードできます。

  2. Google Play がプロファイルを処理し、APK とともにユーザーに直接リリースします。インストール時に、ART はプロファイル内のメソッドを AOT コンパイルします。これにより、メソッドの実行速度が向上します。アプリの起動時やフレーム レンダリング時に使用されるメソッドがプロファイルに含まれていれば、起動時間が短くなったり、ジャンクが減ったりする可能性があります。

  3. このフローはクラウド プロファイルの集約と連携し、時間の経過に伴うアプリの実際の使用に基づいてパフォーマンスを微調整します。

図 1. この図は、アップロードからエンドユーザーへの配信までの、ベースライン プロファイルのワークフローと、そのワークフローがクラウド プロファイルとどのように関連しているかを示しています。

クラウド プロファイル

クラウド プロファイルでは、追加の形式の PGO がベースライン プロファイルとともに提供されます。PGO は Google Play ストアで集約され、インストール時のコンパイル用に配布されます。

クラウド プロファイルはアプリに対する実際のユーザー操作によって機能しますが、アップデートの配布には数日から数週間かかるため、可用性が制限されます。プロファイルが完全に配布されるまで、新しいアプリまたは更新されたアプリのユーザーは、最適ではないパフォーマンスでアプリを利用することになります。また、クラウド プロファイルは、Android 9(API レベル 29)以降を搭載している Android デバイスのみをサポートしており、現時点ではユーザーが一定数以上いるアプリにのみ適しています。

Android バージョン間のコンパイル動作

Android プラットフォームの各バージョンでは、これまでさまざまなアプリのコンパイル方法が採用され、それぞれの方法にトレードオフがありました。ベースライン プロファイルは、すべてのインストールにプロファイルを提供することで、以前のコンパイル方法を改善します。

Android のバージョン コンパイル方法 最適化アプローチ
5~6(API レベル 21~23) 完全 AOT アプリ全体がインストール時に最適化されるため、アプリ使用時の待ち時間が長くなって RAM やディスクの使用量が増えます。また、ディスクからコードを読み込む時間が長くなるため、コールド スタートアップに時間がかかることがあります。
7~8.1(API レベル 24~27) 部分 AOT(ベースライン プロファイル) アプリ モジュールで依存関係が定義されている場合は、初回実行時に androidx.profileinstaller によってベースライン プロファイルがインストールされます。ART は、アプリ使用時に他のプロファイル ルールを追加し、デバイスがアイドル状態のときにそれらをコンパイルすることで、ベースライン プロファイルの内容をさらに改善できます。これにより、ディスク容量と、ディスクからコードを読み込む時間が最適化され、アプリの待ち時間が短くなります。
9(API レベル 28) 以降 部分 AOT(ベースライン + クラウド プロファイル) Google Play がアプリのインストール時にベースライン プロファイルを使用し、APK とクラウド プロファイル(利用可能な場合)を最適化します。インストール後、ART プロファイルは Google Play にアップロードおよび集約されます。集約したプロファイルは、後日ユーザーがアプリをインストールまたは更新する際にクラウド プロファイルとして提供されます。

既知の問題

  • App Bundle から APK をビルドする際に、ベースライン プロファイルが正しくパッケージ化されません。この問題を解決するには、com.android.tools.build:gradle:7.3.0 以上を適用してください。(問題)。

  • ベースライン プロファイルはプライマリ classes.dex ファイルに対してのみ正しくパッケージ化されます。これは複数の .dex ファイルがあるアプリに影響します。この問題を解決するには、com.android.tools.build:gradle:7.3.0 以上を適用してください。

  • user(root 権限のない)ビルドで、ART プロファイル キャッシュをリセットできません。この問題を回避するために、androidx.benchmark:benchmark-macro-junit4:1.1.0 には、ベンチマーク中にアプリを再インストールする修正が含まれています(問題)。

  • Android Studio のプロファイラで、アプリのプロファイリング時にベースライン プロファイルがインストールされません(問題)。

  • Gradle 以外のビルドシステム(Bazel、Buck など)では、ベースライン プロファイルを出力 APK に組み込むことができません。

  • Google Play ストア以外のアプリ配信チャネルでは、インストール時にベースライン プロファイルを使用できない場合があります。こうしたチャネルを通じてユーザーがインストールされているアプリを使用することは、バックグラウンド dexopt が実行されない限り(多くの場合一晩中)メリットはありません。

  • ビルド コンパイラが src/main フォルダに受け入れるのは 1 つの baseline-prof.txt のみです。他のフレーバーやビルドタイプのファイルは反映されません。この状況は現在も改善中です。

  • バッテリーを最適化すると、プロファイルのインストールが妨げられることがあります。バッテリーを最適化している場合は、プロファイルを効率的にインストールできるよう、ベンチマーク デバイスで最適化を無効にしてください。

  • ベンチマークと本番環境とでは、パフォーマンスの改善に差が生じることがあります。これは、ローカル ベンチマークでパフォーマンスを測定する際に、ベースライン プロファイルが有効な場合と無効な場合があるためです。本番環境のアプリでは、アプリの新しい部分がベースライン プロファイルに追加されると、その部分がコントリビューション ライブラリを介してプロファイリングされた状態になるため、測定値が向上します。