Macrobenchmark ライブラリは、アプリの起動や複雑な UI 操作(RecyclerView
のスクロールやアニメーションの実行など)のようなアプリ内の比較的大きな領域に対応するユースケースをテストするために使用します。比較的小さな領域のコードをテストする場合は、Microbenchmark ライブラリを参照してください。
ライブラリは、Android Studio コンソールと JSON ファイルの両方に詳細情報付きのベンチマーク結果を出力します。Android Studio に読み込んで分析できるトレース ファイルも提供します。
継続的インテグレーションでベンチマークを実行するで説明しているように、継続的インテグレーション(CI)環境で Macrobenchmark ライブラリを使用します。
ベースライン プロファイルは、Macrobenchmark を使用して生成できます。以下のガイドに沿って Marcobenchmark ライブラリを設定してから、ベースライン プロファイルを作成してください。
プロジェクトの設定
Macrobenchmark は、Android Studio の最新バージョンで使用することをおすすめします。最新バージョンの IDE は、Macrobenchmark を統合する新機能を備えているからです。
Macrobenchmark モジュールを設定する
マクロ ベンチマークを行うには、アプリを測定するテストを実行するために、アプリコードとは別個の com.android.test
モジュールが必要です。
Android Studio には、Macrobenchmark モジュールの設定を簡素化するテンプレートが用意されています。ベンチマーク モジュール テンプレートを使用すると、アプリ モジュールによってビルドされたアプリを測定するためのモジュール(サンプル起動ベンチマークなど)が、プロジェクト内に自動的に作成されます。
モジュール テンプレートを使用して新しいモジュールを作成する手順は次のとおりです。
Android Studio の [Project] パネルでプロジェクトまたはモジュールを右クリックして、[New] > [Module] をクリックします。
[Templates] ペインで [Benchmark] を選択します。
ターゲット アプリ(ベンチマーク対象のアプリ)に加えて、新しい Macrobenchmark モジュールのパッケージ名とモジュール名をカスタマイズできます。
[Finish] をクリックします。
アプリを設定する
アプリ(マクロ ベンチマークの「ターゲット」)のベンチマークを行うには、そのアプリを profileable
にして、パフォーマンスに影響を与えずに詳細なトレース情報を読み取れるようにする必要があります。モジュール ウィザードを使用すると、アプリの AndroidManifest.xml
ファイルに <profileable>
タグが自動的に追加されます。
できる限りリリース バージョン(製品版)に近くなるようにベンチマーク対象のアプリを構成します。アプリはデバッグ不可として設定します。パフォーマンスを高めるために、圧縮をオンにすることをおすすめします。そのためには、通常、リリース バリアントのコピーを作成します。これは同じ処理を行いますが、デバッグキーを使用してローカルで署名されます。または、initWith
を使用して Gradle に処理を指示することもできます。
Groovy
buildTypes { val release = getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } create("benchmark") { initWith(release) signingConfig = signingConfigs.getByName("debug") proguardFiles("benchmark-rules.pro") } }
Kotlin
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") } }
Gradle 同期を実行し、左側の [Build Variants] パネルを開いて、アプリと Macrobenchmark モジュールの両方のベンチマーク バリアントを選択します。これにより、ベンチマークを実行すると、確実にアプリの正しいバリアントをビルドしてテストできるようになります。
(省略可)マルチモジュール アプリを設定する
アプリに複数の Gradle モジュールがある場合は、コンパイルするビルド バリアントをビルド スクリプトが認識できるようにする必要があります。そうしないと、新しく追加された benchmark
buildType が原因でビルドが失敗し、次のエラー メッセージが表示されます。
> Could not resolve project :shared.
Required by:
project :app
> No matching variant of project :shared was found.
...
この問題を解決するには、:macrobenchmark
モジュールと :app
モジュールの benchmark
buildType に matchingFallbacks
プロパティを追加します。残りの Gradle モジュールについては、以前と同じ構成で問題ありません。
Groovy
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf('release') }
プロジェクト内のビルド バリアントを選択する際は、:app
と :macrobenchmark
の各モジュールには benchmark
を、アプリ内の他のモジュールには release
を選択します。次の画像をご覧ください。
詳しくは、バリアント識別による依存関係の管理をご覧ください。
(省略可)プロダクト フレーバーを設定する
アプリに複数のプロダクト フレーバーを設定している場合は、:macrobenchmark
モジュールを構成して、ビルドとベンチマークを行うアプリのプロダクト フレーバーをモジュールが認識できるようにする必要があります。この構成を行わないと、複数の Gradle モジュールがある場合と似たビルドエラーが発生する可能性があります。
Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
> Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
> Could not resolve project :app.
Required by:
project :macrobenchmark
> The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
- demoBenchmarkRuntimeElements
- productionBenchmarkRuntimeElements
All of them match the consumer attributes:
...
このガイドでは、次のスニペットに示すように、:app
モジュールで 2 つのプロダクト フレーバー(demo
と production
)を使用します。
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
複数のプロダクト フレーバーでベンチマークを構成するには、以下の 2 つの方法があります。
missingDimensionStrategy
を使用する
:macrobenchmark
モジュールの defaultConfig
で missingDimensionStrategy
を指定すると、ビルドシステムに対してフレーバー ディメンションにフォールバックするよう指示できます。モジュールにディメンションが見つからない場合は、使用するディメンションを指定する必要があります。次の例では、デフォルトのディメンションとして production
フレーバーを使用しています。
Groovy
defaultConfig { missingDimensionStrategy "environment", "production" }
Kotlin
defaultConfig { missingDimensionStrategy("environment", "production") }
このように、:macrobenchmark
モジュールは指定されたプロダクト フレーバーのビルドとベンチマークのみを行うことができます。これは、ベンチマーク対象の適切な構成を持つプロダクト フレーバーが 1 つのみであることがわかっている場合に便利です。
:macrobenchmark
モジュールでプロダクト フレーバーを定義する
他のプロダクト フレーバーをビルドしてベンチマークを行う場合は、:macrobenchmark
モジュールでそれらを定義する必要があります。指定方法は :app
モジュールの場合と似ていますが、productFlavors
を dimension
に割り当てるだけです。他の設定は必要ありません。
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
プロジェクトを定義して同期したら、[Build Variants] ペインから目的のビルド バリアントを選択します。
詳しくは、バリアント マッチングに関連するビルドエラーを解決するをご覧ください。
Macrobenchmark クラスを作成する
ベンチマーク テストは、Macrobenchmark ライブラリの MacrobenchmarkRule
JUnit4 Rule API によって提供されます。この API には、ターゲット アプリを実行してベンチマークを行う方法についてさまざまな条件を指定できる measureRepeated
メソッドが含まれています。
少なくとも、ターゲット アプリの packageName
、測定する metrics
、ベンチマークの実行対象である iterations
の数を指定する必要があります。
Kotlin
@LargeTest @RunWith(AndroidJUnit4::class) class SampleStartupBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test fun startup() = benchmarkRule.measureRepeated( packageName = TARGET_PACKAGE, metrics = listOf(StartupTimingMetric()), iterations = DEFAULT_ITERATIONS, setupBlock = { // Press home button before each run to ensure the starting activity isn't visible. pressHome() } ) { // starts default launch activity startActivityAndWait() } }
Java
@LargeTest @RunWith(AndroidJUnit4.class) public class SampleStartupBenchmark { @Rule public MacrobenchmarkRule benchmarkRule = new MacrobenchmarkRule(); @Test public void startup() { benchmarkRule.measureRepeated( /* packageName */ TARGET_PACKAGE, /* metrics */ Arrays.asList(new StartupTimingMetric()), /* iterations */ 5, /* measureBlock */ scope -> { // starts default launch activity scope.startActivityAndWait(); return Unit.INSTANCE; } ); } }
ベンチマークをカスタマイズする方法のすべてのオプションについては、ベンチマークをカスタマイズするセクションをご覧ください。
ベンチマークを実行する
Android Studio 内からテストを実行して、デバイス上のアプリのパフォーマンスを測定します。次の画像に示すように、テストクラスまたはテストメソッドの横にあるガター アクションを使用して、他の @Test
を実行する場合と同じようにベンチマークを実行できます。
または、コマンドラインから connectedCheck コマンドを実行して、Gradle モジュール内のすべてのベンチマークを実行することもできます。
./gradlew :macrobenchmark:connectedCheck
単一のテストを実行するには、次のようにします。
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup
継続的インテグレーションでベンチマークを実行およびモニタリングする方法については、CI でベンチマークを実行するをご覧ください。
ベンチマークの結果
ベンチマークの実行が成功すると、指標は Android Studio 内に直接表示されます。また、JSON ファイルの CI 使用状況にも出力されます。測定される反復処理は、それぞれが個別のシステム トレースをキャプチャします。結果トレースを開くには、次の画像に示すように、[Test Results] ペインにあるいずれかのリンクをクリックします。
トレースが読み込まれると、Android Studio によって、分析するプロセスの選択を求められます。選択するターゲット アプリのプロセスは事前入力されます。
トレース ファイルが読み込まれると、Studio は CPU Profiler ツールで結果を表示します。
JSON レポートとプロファイリング トレースも、デバイスからホストに自動的にコピーされます。レポートは、ホストマシンの次の場所に書き込まれます。
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
手動でトレース ファイルにアクセスする
Perfetto ツールを使用してトレース ファイルを分析する場合は、追加の手順が必要です。Perfetto では、トレース中にデバイスで実行されているすべてのプロセスを検査できます。これに対して、Android Studio の CPU Profiler では、検査は単一のプロセスに限定されます。
Android Studio から、または Gradle コマンドラインからテストを呼び出した場合、トレース ファイルはデバイスからホストに自動的にコピーされます。レポートは、ホストマシンの次の場所に書き込まれます。
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
ホストシステムにトレース ファイルが作成されたら、Android Studio の [File] > [Open] メニューからトレース ファイルを開くことができます。前のセクションで示したプロファイラ ツールのビューが表示されます。
構成エラー
アプリが誤って(デバッグ可能またはプロファイル不可に)構成されている場合、Macrobenchmark は不正確または不完全な測定をレポートするのではなく、エラーをスローします。androidx.benchmark.suppressErrors
引数を使用すると、このようなエラーの出力を抑制できます。
エミュレータまたは電池容量の少ないデバイスで測定しようとした場合も、コアの可用性とクロック速度が損なわれる可能性があるため、エラーがスローされます。
ベンチマークをカスタマイズする
measureRepeated
関数は、ライブラリが収集する指標、アプリの起動とコンパイルの方法、ベンチマークの実行対象となる反復処理の数に影響を及ぼすさまざまなパラメータを受け取ります。
指標をキャプチャする
指標は、ベンチマークから抽出される主要な情報タイプです。指定できるオプションは、StartupTimingMetric
、FrameTimingMetric
、TraceSectionMetric
です。これらのオプションについて詳しくは、指標のキャプチャに関するページをご覧ください。
カスタム イベントを使用してトレースデータを改善する
場合によっては、カスタム トレース イベントを使用したアプリのインストルメント化が有用です。カスタム トレース イベントは他のトレース レポートに表示され、アプリ固有の問題を特定するために役立ちます。カスタム トレース イベントの作成方法については、カスタム イベントを定義するガイドをご覧ください。
CompilationMode
マクロ ベンチマークでは、CompilationMode を指定し、アプリを DEX バイトコード(APK 内のバイトコード形式)からマシンコード(プリコンパイル後の C++ のようなコード)にプリコンパイルする量を定義できます。
デフォルトでは、マクロ ベンチマークは CompilationMode.DEFAULT
で実行されます。この場合、Android 7(API レベル 24)以降ではベースライン プロファイル(利用可能な場合)がインストールされます。Android 6(API レベル 23)以前では、このコンパイル モードの場合、デフォルトのシステム動作として APK はフルコンパイルされます。
ターゲット アプリにベースライン プロファイルと ProfileInstaller
ライブラリの両方が含まれている場合は、ベースライン プロファイルをインストールできます。
Android 7 以降では、CompilationMode
をカスタマイズすることにより、デバイス上のプリコンパイルの量を調整して、さまざまなレベルの事前(AOT)コンパイルまたは JIT キャッシュ処理を模倣できます。CompilationMode.Full
、CompilationMode.Partial
、CompilationMode.None
をご覧ください。
この機能は、ART コンパイル コマンドをベースにして構築されています。ベンチマーク間の干渉が起こらないようにするため、各ベンチマークは開始前にプロファイル データを消去します。
StartupMode
アクティビティの起動を実行するには、事前定義された起動モード(COLD
、WARM
、HOT
のいずれか)を渡します。このパラメータにより、テスト開始時のアクティビティの起動方法とプロセスの状態が変更されます。
起動の種類について詳しくは、Android Vitals の起動に関するドキュメントをご覧ください。
サンプル
サンプル プロジェクトは、GitHub の android/performance-samples リポジトリの一部として入手できます。
フィードバックを送信する
Jetpack Macrobenchmark に関する問題の報告または機能リクエストの送信については、公開されている Issue Tracker をご利用ください。