Verwenden Sie die Macrobenchmark-Bibliothek, um größere Anwendungsfälle Ihrer App zu testen, einschließlich App-Start und komplexer UI-Manipulationen, z. B. Scrollen in einer LazyColumn oder Ausführen von Animationen. Wenn Sie kleinere Bereiche Ihres Codes testen möchten, lesen Sie den Abschnitt Microbenchmark. Auf dieser Seite wird beschrieben, wie Sie die Macrobenchmark-Bibliothek einrichten.
Die Bibliothek gibt Benchmarking-Ergebnisse in der Android Studio-Konsole und in einer JSON-Datei mit weiteren Details aus. Außerdem werden Trace-Dateien bereitgestellt, die Sie in Android Studio laden und analysieren können.
Verwenden Sie die Macrobenchmark-Bibliothek in einer CI-Umgebung (Continuous Integration), wie unter Benchmark in Continuous Integration beschrieben.
Mit Macrobenchmark können Sie Basisprofile erstellen. Richten Sie zuerst die Macrobenchmark-Bibliothek ein. Anschließend können Sie ein Baseline-Profil erstellen.
Macrobenchmark ist das empfohlene Tool zum Testen von Benutzeroberflächen, die mit Jetpack Compose erstellt wurden. Informationen zum Schreiben von UI Automator-Tests, die mit Ihren Compose-Knoten interagieren, finden Sie unter Interoperabilität.
Projekt einrichten
Wir empfehlen, Macrobenchmark mit der aktuellen Version von Android Studio zu verwenden.
Macrobenchmark-Modul einrichten
Für Makro-Benchmarks ist ein com.android.test-Modul erforderlich, das vom App-Code getrennt ist und für die Ausführung der Tests zur Messung der App-Leistung verantwortlich ist.
In Android Studio ist eine Vorlage verfügbar, mit der sich das Einrichten des Macrobenchmark-Moduls vereinfachen lässt. Mit der Vorlage für das Benchmarking-Modul wird automatisch ein Modul in Ihrem Projekt erstellt, mit dem die von einem App-Modul erstellte App gemessen wird, einschließlich eines Beispiels für einen Start-Benchmark.
So erstellen Sie ein neues Modul mit der Modulvorlage:
Klicken Sie in Android Studio im Bereich Projekt mit der rechten Maustaste auf Ihr Projekt oder Modul und wählen Sie Neu > Modul aus.
Wählen Sie im Bereich Vorlagen die Option Benchmark aus. Du kannst die Ziel-App, also die App, für die ein Benchmark erstellt werden soll, sowie den Paket- und Modulnamen für das neue Macrobenchmark-Modul anpassen.
Klicken Sie auf Fertig.
App einrichten
Um eine App zu benchmarken, die als Ziel des Makrobenchmarks bezeichnet wird, muss die App profileable sein. Dadurch können detaillierte Trace-Informationen gelesen werden, ohne die Leistung zu beeinträchtigen. Der Modulassistent fügt das Tag <profileable> automatisch in die Datei AndroidManifest.xml der App ein.
Achte darauf, dass die Ziel-App ProfilerInstaller 1.3 oder höher enthält. Diese Version wird von der Macrobenchmark-Bibliothek benötigt, um die Profilerfassung und das Zurücksetzen sowie das Löschen des Shader-Caches zu ermöglichen.
Konfigurieren Sie die Benchmark-Anwendung so nah wie möglich an der Release-Version oder Produktion. Richte sie als nicht debugfähig und vorzugsweise mit aktivierter Reduzierung ein, um die Leistung zu verbessern. Dazu erstellen Sie in der Regel eine Kopie der Release-Variante, die dieselbe Leistung bietet, aber lokal mit Debug-Schlüsseln signiert ist.
Alternativ können Sie initWith verwenden, um Gradle anzuweisen, dies für Sie zu tun:
Kotlin
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") } }
Groovy
buildTypes { release { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "keep-rules.pro" ) // In real app, this would use its own release keystore signingConfig = signingConfigs.getByName("debug") baselineProfile.automaticGenerationDuringBuild = true } }
Damit beim Ausführen des Benchmarks die richtige Variante Ihrer App erstellt und getestet wird, wie in Abbildung 2 dargestellt, gehen Sie so vor:
- Führen Sie eine Gradle-Synchronisierung durch.
- Öffnen Sie den Bereich Build-Varianten.
- Wählen Sie die Benchmark-Variante der App und des Macrobenchmark-Moduls aus.
Optional: App mit mehreren Modulen einrichten
Wenn deine App mehr als ein Gradle-Modul hat, müssen deine Build-Skripts wissen, welche Build-Variante kompiliert werden soll. Fügen Sie das Attribut matchingFallbacks dem Build-Typ benchmark der Module :macrobenchmark und :app hinzu. Die restlichen Gradle-Module können dieselbe Konfiguration wie zuvor haben.
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") }
Groovy
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
Ohne diese Einstellung führt der neu hinzugefügte Build-Typ benchmark dazu, dass der Build fehlschlägt. Es wird die folgende Fehlermeldung angezeigt:
> Could not resolve project :shared.
Required by:
project :app
> No matching variant of project :shared was found.
...
Wählen Sie bei der Auswahl der Build-Varianten in Ihrem Projekt benchmark für die Module :app und :macrobenchmark und release für alle anderen Module in Ihrer App aus, wie in Abbildung 3 dargestellt:
Weitere Informationen finden Sie unter Build-Fehler im Zusammenhang mit dem Variantenabgleich beheben.
Optional: Produktvarianten einrichten
Wenn Sie in Ihrer App mehrere Produktvarianten festgelegt haben, konfigurieren Sie das :macrobenchmark-Modul so, dass es weiß, welche Produktvariante Ihrer App erstellt und einem Benchmark unterzogen werden soll.
In den Beispielen auf dieser Seite werden die beiden Produktvarianten im :app-Modul, demo und production, verwendet, wie im folgenden Snippet gezeigt:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
Ohne diese Konfiguration erhalten Sie möglicherweise einen Build-Fehler, der dem durch mehrere Gradle-Module verursachten Fehler ähnelt:
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:
...
In den folgenden beiden Abschnitten werden Möglichkeiten zum Konfigurieren von Benchmarking mit mehreren Produktvarianten beschrieben.
missingDimensionStrategy verwenden
Wenn Sie missingDimensionStrategy in der defaultConfig des :macrobenchmark-Moduls angeben, wird das Build-System angewiesen, auf die Flavor-Dimension zurückzugreifen. Geben Sie an, welche Dimensionen verwendet werden sollen, wenn Sie sie nicht im Modul finden.
Im folgenden Beispiel wird die Variante production als Standarddimension verwendet:
Kotlin
defaultConfig { missingDimensionStrategy("environment", "production") }
Groovy
defaultConfig { missingDimensionStrategy "environment", "production" }
Auf diese Weise kann das :macrobenchmark-Modul nur die angegebene Produktvariante erstellen und benchmarken. Das ist hilfreich, wenn Sie wissen, dass nur eine Produktvariante die richtige Konfiguration für das Benchmarking hat.
Produktvarianten im Modul „:macrobenchmark“ definieren
Wenn Sie andere Produktvarianten erstellen und vergleichen möchten, definieren Sie sie im Modul :macrobenchmark. Geben Sie sie ähnlich wie im Modul :app an, weisen Sie aber nur productFlavors einem dimension zu. Es sind keine weiteren Einstellungen erforderlich:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
Nachdem Sie das Projekt definiert und synchronisiert haben, wählen Sie im Bereich Build-Varianten die entsprechende Build-Variante aus, wie in Abbildung 4 dargestellt:
Weitere Informationen finden Sie unter Build-Fehler im Zusammenhang mit dem Variantenabgleich beheben.
Macrobenchmark-Klasse erstellen
Benchmarktests werden über die JUnit4-Regel-API MacrobenchmarkRule in der Macrobenchmark-Bibliothek bereitgestellt. Sie enthält eine measureRepeated-Methode, mit der Sie verschiedene Bedingungen für die Ausführung und das Benchmarking der Ziel-App angeben können.
Sie müssen mindestens die packageName der Ziel-App, die zu messende metrics und die Anzahl der iterations angeben, die der Benchmark ausführen muss.
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, ) { // starts default launch activity uiAutomator { startApp(TARGET_PACKAGE) } } }
Informationen zu allen Optionen zum Anpassen des Benchmarks finden Sie im Abschnitt Benchmarks anpassen.
Benchmark-Compose-UI-Interaktionen
Im vorherigen Beispiel wurde der App-Start gemessen. Häufig möchten Sie aber die UI-Leistung messen, z. B. Frame-Drops (Ruckeln) beim Scrollen.
Wenn Sie eine Jetpack Compose-Anwendung benchmarken möchten, z. B. um FrameTimingMetric beim Scrollen in einer LazyColumn zu messen, können Sie UI Automator verwenden, um direkt mit Ihren Compose-Knoten zu interagieren, wie im folgenden Snippet gezeigt.
@LargeTest
@RunWith(AndroidJUnit4::class)
class ComposeScrollBenchmark {
@get:Rule
val benchmarkRule = MacrobenchmarkRule()
@Test
fun scrollLazyColumn() = benchmarkRule.measureRepeated(
packageName = "com.example.compose.app",
metrics = listOf(FrameTimingMetric()),
iterations = 5,
startupMode = StartupMode.WARM,
setupBlock = { pressHome() }
) {
startActivityAndWait()
// Find the Compose node using the testTag defined in your app
val lazyColumn = device.findObject(By.res("my_lazy_column"))
// Simulate a scroll gesture to measure FrameTimingMetric
lazyColumn.setGestureMargin(device.displayWidth / 5)
lazyColumn.fling(Direction.DOWN)
}
}
Benchmark ausführen
Führen Sie den Test in Android Studio aus, um die Leistung Ihrer App auf Ihrem Gerät zu messen. Sie können die Benchmarks auf dieselbe Weise ausführen wie alle anderen @Test. Verwenden Sie dazu die Gutter-Aktion neben Ihrer Testklasse oder -methode, wie in Abbildung 5 dargestellt.
Sie können auch alle Benchmarks in einem Gradle-Modul über die Befehlszeile ausführen. Verwenden Sie dazu den Befehl connectedCheck:
./gradlew :macrobenchmark:connectedCheckSie können einen einzelnen Test ausführen, indem Sie Folgendes ausführen:
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startupInformationen zum Ausführen und Überwachen von Benchmarks in der Continuous Integration finden Sie unter Benchmark in Continuous Integration.
Benchmark-Ergebnisse
Nach einem erfolgreichen Benchmarklauf werden die Messwerte direkt in Android Studio angezeigt und für die CI-Nutzung in einer JSON-Datei ausgegeben. Bei jeder gemessenen Iteration wird ein separater System-Trace erfasst. Sie können diese Trace-Ergebnisse öffnen, indem Sie auf die Links im Bereich Testergebnisse klicken, wie in Abbildung 6 dargestellt:
Wenn der Trace geladen ist, werden Sie in Android Studio aufgefordert, den zu analysierenden Prozess auszuwählen. Die Auswahl wird vorab mit dem Ziel-App-Prozess ausgefüllt, wie in Abbildung 7 dargestellt:
Nachdem die Trace-Datei geladen wurde, werden die Ergebnisse in Studio im CPU-Profiler-Tool angezeigt:
JSON-Berichte und alle Profiling-Traces werden ebenfalls automatisch vom Gerät auf den Host kopiert. Diese werden auf dem Hostcomputer am folgenden Speicherort geschrieben:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Manuell auf Trace-Dateien zugreifen
Wenn Sie das Perfetto-Tool zum Analysieren einer Trace-Datei verwenden möchten, sind zusätzliche Schritte erforderlich. Mit Perfetto kannst du alle Prozesse prüfen, die während des Traces auf dem Gerät ausgeführt werden. Der CPU-Profiler von Android Studio beschränkt die Prüfung dagegen auf einen einzelnen Prozess.
Wenn Sie die Tests über Android Studio oder die Gradle-Befehlszeile aufrufen, werden die Trace-Dateien automatisch vom Gerät auf den Host kopiert. Diese werden auf dem Hostcomputer am folgenden Speicherort geschrieben:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
Wenn sich die Trace-Datei auf Ihrem Hostsystem befindet, können Sie sie in Android Studio über das Menü Datei > Öffnen öffnen. Dadurch wird die im vorherigen Abschnitt gezeigte Ansicht des Profiler-Tools angezeigt.
Konfigurationsfehler
Wenn die App falsch konfiguriert ist (debugfähig oder nicht profilierbar), gibt Macrobenchmark einen Fehler zurück, anstatt eine falsche oder unvollständige Messung zu melden. Sie können diese Fehler mit dem Argument androidx.benchmark.suppressErrors unterdrücken.
Macrobenchmark gibt auch Fehler zurück, wenn versucht wird, einen Emulator oder ein Gerät mit niedrigem Akkustand zu messen, was die Verfügbarkeit der Kerne und die Taktgeschwindigkeit beeinträchtigen könnte.
Benchmarks anpassen
Die Funktion measureRepeated akzeptiert verschiedene Parameter, die beeinflussen, welche Messwerte die Bibliothek erfasst, wie Ihre App gestartet und kompiliert wird oder wie viele Iterationen der Benchmark ausführt.
Messwerte erfassen
Messwerte sind die wichtigsten Informationen, die aus Ihren Benchmarks extrahiert werden. Die folgenden Messwerte sind verfügbar:
Weitere Informationen zu Messwerten finden Sie unter Makro-Benchmark-Messwerte erfassen.
Trace-Daten mit benutzerdefinierten Ereignissen verbessern
Es kann nützlich sein, Ihre Anwendung mit benutzerdefinierten Trace-Ereignissen zu instrumentieren, die im restlichen Trace-Bericht angezeigt werden und auf Probleme hinweisen können, die für Ihre Anwendung spezifisch sind. Weitere Informationen zum Erstellen benutzerdefinierter Trace-Ereignisse finden Sie unter Benutzerdefinierte Ereignisse definieren.
CompilationMode
In Macrobenchmarks kann ein CompilationMode angegeben werden, der definiert, wie viel der App aus DEX-Bytecode (dem Bytecode-Format innerhalb eines APK) in Maschinencode (ähnlich wie vorkompiliertes C++) vorkompiliert werden muss.
Standardmäßig werden Macrobenchmarks mit CompilationMode.DEFAULT ausgeführt. Dadurch wird unter Android 7 (API-Level 24) und höher ein Baseline-Profil installiert, sofern verfügbar.
Wenn Sie Android 6 (API-Level 23) oder früher verwenden, wird das APK im Kompilierungsmodus standardmäßig vollständig kompiliert.
Sie können ein Baseline-Profil installieren, wenn die Ziel-App sowohl ein Baseline-Profil als auch die Bibliothek ProfileInstaller enthält.
Unter Android 7 und höher kannst du die CompilationMode anpassen, um den Umfang der Vorkompilierung auf dem Gerät zu beeinflussen und so verschiedene Stufen der Ahead-of-Time-Kompilierung (AOT) oder des JIT-Caching zu simulieren. Siehe CompilationMode.Full, CompilationMode.Partial, CompilationMode.None und CompilationMode.Ignore.
Diese Funktion basiert auf ART-Kompilierungsbefehlen. Bei jedem Benchmark werden die Profildaten vor dem Start gelöscht, um Interferenzen zwischen Benchmarks zu vermeiden.
StartupMode
Wenn Sie eine Aktivität starten möchten, können Sie einen vordefinierten Startmodus übergeben: COLD, WARM oder HOT. Dieser Parameter ändert, wie die Aktivität gestartet wird und wie der Prozessstatus zu Beginn des Tests ist.
Weitere Informationen zu den Starttypen finden Sie unter App-Startzeit.
Beispiele
Ein Beispielprojekt ist im Macrobenchmark-Beispiel des Repositorys auf GitHub verfügbar.
Feedback geben
Wenn Sie Probleme melden oder Feature Requests für Jetpack Macrobenchmark einreichen möchten, rufen Sie die öffentliche Problemverfolgung auf.
Empfehlungen für Sie
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Makro-Benchmark-Messwerte erfassen
- Baseline-Profile erstellen {:#creating-profile-rules}
- Messung mit der Macrobenchmark-Bibliothek automatisieren {:#measuring-optimization}