ベースライン プロファイルの概要

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

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

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

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

ベースライン プロファイルを使用すると、アプリの起動、画面間の移動、コンテンツのスクロールなどのクリティカル ユーザー操作でコードの事前コンパイルが可能になり、初回実行時からスムーズに行えるようになります。ベースライン プロファイルでアプリの速度と応答性を高めることで、1 日のアクティブ ユーザー数が増加し、平均リピーター率が向上します。

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

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

起動プロファイル

起動プロファイルはベースライン プロファイルと類似していますが、デバイス上の最適化のためではなく、コンパイル時に使用されて DEX レイアウトを最適化し、起動時間を短縮します。起動プロファイルとベースライン プロファイルの違いについて詳しくは、ベースライン プロファイルと起動プロファイルを比較するをご覧ください。DEX レイアウトの最適化について詳しくは、DEX レイアウトの最適化と起動プロファイルをご覧ください。

始める

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

プロファイル生成とリリースビルド

ベースライン プロファイル ファイルと起動プロファイル ファイル(baseline-prof.txtstartup-prof.txt など)を生成するときに必要なビルド構成と、これらのプロファイルを使用する最終リリース APK をビルドするときに必要なビルド構成の違いを理解しておくことが重要です。

プロファイル ファイル(benchmark など)を生成する場合:

生成されたプロファイル ルールがコードのメソッド シグネチャと正確に一致するようにするには、プロファイル生成に使用されるビルド バリアントの難読化と最適化(R8)をオフにする必要があります。このバリアントは、難読化と最適化が有効になっているリリースビルド バリアントとは異なる必要があります。これを行うには、プロファイル生成ビルド バリアントの isMinifyEnabled = false を設定します。ベースライン プロファイルの Gradle プラグインを使用していない場合は、-dontobfuscate-dontoptimize が適用されていることも確認する必要があります。ベースライン プロファイル Gradle プラグインは、この構成を自動的に処理します。

最終リリース APK をビルドする場合:

リリースビルドには、難読化、軽量化、最適化のメリットを活かすために、常に isMinifyEnabled = true を含める必要があります。R8 は、難読化されていないプロファイル ファイルのルールを自動的に書き換えて、リリース APK の難読化および最適化されたコードと一致させます。DEX レイアウトの最適化(起動プロファイルによって駆動)を有効にするには、リリースアプリを難読化し、すべての最適化を有効にして R8 を使用する必要があります。

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

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

ベースライン プロファイルの作成と管理には、最新バージョンの AGP を使用することをおすすめします。AGP のバージョン別の主な機能は次のとおりです。

AGP バージョン 機能
8.4 Gradle ラッパー コマンドライン ツールまたは Android Studio を使用してデバッグ不可能なビルドをローカルにインストールすると、ベースライン プロファイルがインストールされるため、ローカル リリースビルドのパフォーマンスが本番環境に近づきます。この更新は、ベースライン プロファイルのプロダクション パフォーマンスには影響しません。
8.3
  • 完全なソースセット ディレクトリのサポート(ライブラリ モジュール): 複数のベースライン プロファイルのソースファイルを宣言し、バリアントに対応したディレクトリ(src/free/generated/baselineProfiles/baseline-prof1.txt など)をライブラリ モジュールだけでなくアプリ モジュールにも使用できるようになりました。
  • ベースライン プロファイルには脱糖されたクラスが含まれます。
8.2
  • R8 のルールの書き換え: D8 と R8 は、人が読める形式のベースライン プロファイル ルールと起動プロファイル ルールを変換し、アプリのパフォーマンスを最適化するために必要なすべてのルールを完全にキャプチャできます。これにより、圧縮されていないビルドからプロファイルを生成し、圧縮されたリリースビルドに適用できます。メソッドのベースライン プロファイルのカバレッジが最大で 30% 増加し、アプリのパフォーマンスが最大で 15% 向上します。
  • 起動プロファイル: この新しいタイプのベースライン プロファイルを生成して、DEX 内のコードのレイアウトを伝えます。起動のパフォーマンスがさらに最大で 15% 向上します。大規模なアプリでは、このパフォーマンスはより大きく向上します。
8.0 推奨最小バージョン: ベースライン プロファイル Gradle プラグインを使用し、単一の Gradle タスクでベースライン プロファイルを生成します。
  • 完全なソースセット ディレクトリのサポート(ライブラリ モジュール): 複数のベースライン プロファイルのソースファイルを宣言し、バリアントに対応したディレクトリ(src/free/generated/baselineProfiles/baseline-prof1.txt など)を使用できるようになりました。
7.4 サポートされる最小バージョン: アプリは、ライブラリからベースライン プロファイルを使用し、src/main/baseline-prof.txt ファイルで独自のベースライン プロファイルを提供できます。
  • App Bundle から APK をビルドすると、ベースライン プロファイルが正しくパッケージ化されます(問題 #230361284)。
  • 複数の .dex ファイルがあるアプリの場合、ベースライン プロファイルはプライマリ .dex ファイルに対して正しくパッケージ化されます。
  • D8 と R8 は、isMinifyEnabledfalse に設定されているビルドから起動プロファイルを生成することをサポートしています。

バリアント対応のプロファイル ソース設定

アプリケーションに Android Gradle プラグイン(AGP)バージョン 8.0 を、ライブラリに AGP バージョン 8.3 を使用すると、ベースライン プロファイル ルールを専用のソースセット ディレクトリに配置できます。これにより、単一の固定パス(src/main/baseline-prof.txt など)の制約を超えて、複数のファイルを有効にできます。

これにより、堅牢なバリアント サポートが実現し、特定のビルド フレーバーとタイプに合わせて調整された個別のベースライン プロファイル(src/variant/baselineProfiles/ などのディレクトリを使用)を定義できます。これにより、パフォーマンス最適化ルールが、固有のアプリケーションまたはライブラリ バイナリごとに正確に適用されます。

プロファイル生成の例

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

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

    @Test
    fun appStartupAndUserJourneys() {
        baselineProfileRule.collect(packageName = PACKAGE_NAME) {
            uiAutomator {
                // App startup journey.
                startApp(PACKAGE_NAME)

                // Find and click elements using the new DSL
                onElement { textAsString() == "COMPOSE LAZYLIST" }.click()
                onElement { viewIdResourceName == "myLazyColumn" }.also {
                    it.fling(Direction.DOWN)
                    it.fling(Direction.UP)
                }
                pressBack()
            }
        }
    }
}

UI Automator ライブラリを使用してユーザー ジャーニーを自動化する方法の詳細については、UI Automator で自動テストを作成するをご覧ください。

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

追加すべき要素

アプリでベースライン プロファイルを使用する場合、アプリの起動コードと、画面間のナビゲーションやスクロールなどの一般的なユーザー操作を含めることができます。登録、ログイン、支払いなどのフロー全体を収集することも可能です。重要と判断したユーザー ジャーニーについては、ベースライン プロファイルを利用することで、ランタイム パフォーマンスを改善できます。

パフォーマンスを改善するさまざまな方法をテストしている場合は、両方のテスト群にベースライン プロファイルを含めることを検討してください。両方に含めることにより、コンパイル済みのコードをすべてのユーザーが同様に実行するようになり、結果を解釈しやすくなります。

ライブラリが提供する独自のベースライン プロファイルをリリースの際に配布することで、アプリのパフォーマンスを改善できます。たとえば、Jetpack Compose のパフォーマンスについてのページで「ベースライン プロファイルを使用する」セクションをご覧ください。

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

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

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

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

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

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

ベースライン プロファイルと起動プロファイルを比較する

ベースライン プロファイル Gradle プラグインを使用して、プロファイル ファイルを定義して生成します。このプラグインはビルドプロセスにフックし、AGP は人が読めるプロファイル ルールをバイナリ形式にコンパイルします。このバイナリ形式は、APK または AAB 内の baseline.prof としてパッケージ化され、1.5 MB 未満であれば、ART がデバイス上のコンパイルに効果的に使用できます。

通常、生成されるこれらのプロファイル ファイルの名前は startup-prof.txtbaseline-prof.txt です。特にスタートアップに重点を置いている場合、コンテンツが似ているように見えることがありますが、これらは異なる目的を果たし、異なる段階でパフォーマンスに影響します。

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

ベースライン プロファイル ファイルには、Android ランタイム(ART)が頻繁に使用されるコードパスをプリコンパイルするために使用する包括的なルールのセットが含まれています。これにより、起動だけでなくアプリのパフォーマンスも最適化されます。

ベースライン プロファイル ファイルは通常、スタートアップ プロファイルにあるルールのスーパーセットです。このファイルには、アプリの起動の最適化に必要なすべてのルール(baselineProfile Gradle タスクで生成)と、他の重要なユーザー ジャーニーの追加プロファイルが含まれています。たとえば、スクロールや異なる画面間の移動などです。

これらの追加の非起動ルールは、includeInStartupProfile 構成フィールドの値に関係なく生成されます。

スタートアップ プロファイル

スタートアップ プロファイル ファイルには、アプリのスタートアップ パス用に特別に最適化されたルールが含まれています。コンパイル中に、D8 は Java バイトコードを DEX 形式に変換します。R8 はこのファイルを使用して DEX ファイルのレイアウトに影響を与え、重要な起動コードがプライマリ DEX ファイルに配置されて実行が高速化されるようにします。通常、includeInStartupProfile は、アプリの初期表示に不可欠なテストシナリオでのみ true に設定する必要があります。詳細については、スタートアップ プロファイルを作成するをご覧ください。

クラウド プロファイル

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

クラウド プロファイルは実際のユーザーによるアプリの操作によって機能しますが、更新が配信されるまで数時間から数日かかるため、可用性が制限されます。プロファイルが完全に配信されるまで、新しいアプリまたは更新されたアプリのユーザーは、アプリを最適なパフォーマンスで利用できません。また、クラウド プロファイルは、Android 9(API レベル 28)以上を搭載した 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 にアップロードされ、集約されます。集約されたプロファイルは、後日他のユーザーがアプリをインストールまたは更新する際にクラウド プロファイルとして提供されます。

既知の問題

考えられる問題と解決策、回避策を開発中の問題は次のとおりです。

  • OnePlus デバイスなど、一部のデバイスでは権限設定が原因でベースライン プロファイルの生成が失敗する可能性があります。この問題を回避するには、[開発者向けオプション] 設定で [権限モニタリングを無効にする] オプションをオフにします。

  • ベースライン プロファイルの生成は、Gradle で管理されている Test Lab デバイスを含む Firebase Test Lab デバイスではサポートされていません(問題 #285187547)。

  • ライブラリにベースライン プロファイルを適切に提供するには、ベースライン プロファイル Gradle プラグイン 1.2.3 または AGP 8.3 を最低限使用してください(問題 #313992099)。

  • ./gradlew app:generateBaselineProfile コマンドでベースライン プロファイルを生成すると、テスト モジュールのベンチマークも実行され、結果は破棄されます。この場合は、-P android.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile を指定してコマンドを実行することで、ベースライン プロファイルのみを生成できます。この問題は AGP 8.2 で修正されています。

  • すべてのビルドタイプのベースライン プロファイルを生成するコマンド ./gradlew app:generateBaselineProfile は、リリース ビルドタイプのベースライン プロファイルのみを生成します。この問題は AGP 8.1 で修正されています。

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

  • Play ストア内部アプリ共有はベースライン プロファイルをサポートしていませんが、内部テストトラックはサポートしています。

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

参考情報

あなたへのおすすめ