Mit der Macrobenchmark-Bibliothek können Sie größere Anwendungsfälle Ihrer App testen, einschließlich des App-Starts und komplexer UI-Manipulationen wie das Scrollen eines LazyColumn oder das 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 Continuous Integration-Umgebung (CI), wie unter Benchmark in Continuous Integration beschrieben.
Mit Macrobenchmark können Sie Baseline-Profile 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 UIs, 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 neuesten Version von Android Studio zu verwenden.
Macrobenchmark-Modul einrichten
Für Macrobenchmarks ist ein com.android.test-Modul erforderlich, das sich von Ihrem App-Code unterscheidet und für die Ausführung der Tests verantwortlich ist, mit denen Ihre App gemessen wird.
In Android Studio ist eine Vorlage verfügbar, um die Einrichtung von Macrobenchmark-Modulen zu vereinfachen. Mit der Benchmarking-Modulvorlage wird automatisch ein Modul in Ihrem Projekt erstellt, mit dem die von einem App-Modul erstellte App gemessen werden kann. Es enthält auch einen Beispiel-Startup-Benchmark.
So erstellen Sie ein neues Modul mit der Modulvorlage:
Klicken Sie in Android Studio im Bereich Project mit der rechten Maustaste auf Ihr Projekt oder Modul und wählen Sie New > Module aus.
Wählen Sie im Bereich Vorlagen die Option Benchmark aus. Sie können die Ziel-App (die App, die als Benchmark verwendet werden soll) sowie den Paket- und Modulnamen für das neue Macrobenchmark-Modul anpassen.
Klicken Sie auf Fertig.
App einrichten
Wenn Sie eine App, die als Ziel des Makrobenchmarks bezeichnet wird, benchmarken möchten, muss sie profileable sein. So können detaillierte Trace-Informationen gelesen werden, ohne die Leistung zu beeinträchtigen. Der Modul-Assistent fügt das Tag <profileable> automatisch in die AndroidManifest.xml-Datei der App ein.
Die Ziel-App muss ProfilerInstaller 1.3 oder höher enthalten. Die Macrobenchmark-Bibliothek benötigt diese Version, um das Erfassen und Zurücksetzen von Profilen sowie das Löschen des Shader-Cache zu ermöglichen.
Konfigurieren Sie die Benchmark-App so, dass sie der Release-Version oder der Produktionsversion so weit wie möglich entspricht. Richten Sie sie als nicht debugfähig ein und aktivieren Sie nach Möglichkeit die Minimierung, um die Leistung zu verbessern. In der Regel erstellen Sie dazu eine Kopie der Release-Variante, die dieselbe Funktion hat, aber lokal mit Debug-Schlüsseln signiert wird.
Alternativ können Sie initWith verwenden, um Gradle anzuweisen, dies für Sie zu erledigen:
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 sowohl die richtige Variante Ihrer App erstellt als auch getestet wird (siehe Abbildung 2), gehen Sie so vor:
- Führen Sie eine Gradle-Synchronisierung durch.
- Öffnen Sie den Bereich Build-Varianten.
- Wählen Sie die Benchmark-Variante sowohl der App als auch des Macrobenchmark-Moduls aus.
(Optional) App mit mehreren Modulen einrichten
Wenn Ihre App mehrere Gradle-Module hat, müssen Sie in Ihren Build-Skripten angeben, welche Build-Variante kompiliert werden soll. Fügen Sie die Eigenschaft matchingFallbacks dem Build-Typ benchmark Ihrer 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 beim Auswählen 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 (siehe Abbildung 3):
Weitere Informationen finden Sie unter Build-Fehler im Zusammenhang mit der Variantenauswahl beheben.
(Optional) Produktvarianten einrichten
Wenn in Ihrer App mehrere Produktvarianten festgelegt sind, konfigurieren Sie das :macrobenchmark-Modul so, dass es weiß, welche Produktvariante Ihrer App erstellt und getestet werden soll.
In den Beispielen auf dieser Seite werden die beiden Produktvarianten im Modul :app verwendet: demo und production, 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 kann ein Build-Fehler auftreten, 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 beiden folgenden Abschnitten wird beschrieben, wie Sie Benchmarking mit mehreren Produktvarianten konfigurieren.
missingDimensionStrategy verwenden
Wenn Sie missingDimensionStrategy in der defaultConfig des Moduls :macrobenchmark 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" }
So kann das :macrobenchmark-Modul nur den angegebenen Produkt-Flavor erstellen und testen. Das ist hilfreich, wenn Sie wissen, dass nur ein Produkt-Flavor die richtige Konfiguration für Benchmarks hat.
Produktvarianten im Modul „:macrobenchmark“ definieren
Wenn Sie andere Produktvarianten erstellen und testen möchten, definieren Sie sie im Modul :macrobenchmark. Geben Sie sie ähnlich wie im Modul :app an, weisen Sie productFlavors aber nur einer 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 die entsprechende Build-Variante im Bereich Build Variants aus (siehe Abbildung 4):
Weitere Informationen finden Sie unter Build-Fehler im Zusammenhang mit der Variantenauswahl beheben.
Macrobenchmark-Klasse erstellen
Benchmark-Tests werden über die MacrobenchmarkRule-JUnit4-Regel-API 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 festlegen können.
Sie müssen mindestens die packageName der Ziel-App, die zu messenden metrics und die Anzahl der iterations angeben, die für den Benchmark ausgeführt werden sollen.
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) } } }
Alle Optionen zum Anpassen von Benchmarks finden Sie im Abschnitt Benchmarks anpassen.
Compose-UI-Interaktionen benchmarken
Im vorherigen Beispiel wird der App-Start gemessen. Häufig möchten Sie jedoch 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 eines 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 jede andere @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, indem Sie den Befehl connectedCheck ausführen:
./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 Benchmarks in der 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 Systemtrace erfasst. Sie können diese Trace-Ergebnisse öffnen, indem Sie auf die Links im Bereich Testergebnisse klicken (siehe Abbildung 6):
Wenn der Trace geladen ist, werden Sie in Android Studio aufgefordert, den zu analysierenden Prozess auszuwählen. Die Auswahl wird mit dem Ziel-App-Prozess vorausgefüllt, wie in Abbildung 7 dargestellt:
Nachdem die Tracedatei 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. Sie 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 Tracedatei verwenden möchten, sind zusätzliche Schritte erforderlich. Mit Perfetto können Sie alle Prozesse untersuchen, die während des Traces auf dem Gerät ausgeführt werden. Der CPU-Profiler von Android Studio beschränkt die Untersuchung auf einen einzelnen Prozess.
Wenn Sie die Tests über Android Studio oder über die Gradle-Befehlszeile aufrufen, werden die Tracedateien automatisch vom Gerät auf den Host kopiert. Sie werden auf dem Hostcomputer am folgenden Speicherort gespeichert:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
Wenn Sie die Tracedatei auf Ihrem Hostsystem haben, können Sie sie in Android Studio über File > Open (Datei > Öffnen) im Menü öffnen. Dadurch wird die Profiler-Tool-Ansicht aus dem vorherigen Abschnitt 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 von Kernen und die Taktfrequenz beeinträchtigen kann.
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 durchläuft.
Messwerte erfassen
Messwerte sind die wichtigsten Informationen, die aus Ihren Benchmarks extrahiert werden. Folgende Messwerte sind verfügbar:
Weitere Informationen zu Messwerten finden Sie unter Makro-Benchmark-Messwerte erfassen.
Trace-Daten mit benutzerdefinierten Ereignissen verbessern
Es kann hilfreich sein, Ihre App mit benutzerdefinierten Trace-Ereignissen zu instrumentieren. Diese werden im restlichen Trace-Bericht angezeigt und können helfen, Probleme zu identifizieren, die speziell für Ihre App gelten. 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 in einem APK) in Maschinencode (ähnlich wie vorkompiliertes C++) vorkompiliert werden muss.
Standardmäßig werden Makrobenchmarks mit CompilationMode.DEFAULT ausgeführt. Dadurch wird ein Baseline-Profil – sofern verfügbar – auf Geräten mit Android 7 (API‑Level 24) und höher installiert.
Wenn Sie Android 6 (API-Level 23) oder früher verwenden, wird das APK standardmäßig im Kompilierungsmodus vollständig kompiliert.
Sie können ein Baseline-Profil installieren, wenn die Ziel-App sowohl ein Baseline-Profil als auch die ProfileInstaller-Bibliothek enthält.
Unter Android 7 und höher können Sie die CompilationMode anpassen, um die Menge der Vorabkompilierung auf dem Gerät zu beeinflussen und so verschiedene Stufen der Ahead-of-Time-Kompilierung (AOT) oder des JIT-Caching zu simulieren. Weitere Informationen finden Sie unter CompilationMode.Full, CompilationMode.Partial, CompilationMode.None und CompilationMode.Ignore.
Diese Funktion basiert auf ART-Kompilierungsbefehlen. Bei jedem Benchmark werden die Profildaten gelöscht, bevor er gestartet wird, um Störungen zwischen den Benchmarks zu vermeiden.
StartupMode
Um eine Aktivität zu starten, 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 aussieht.
Weitere Informationen zu den Arten des Starts 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, verwenden Sie die öffentliche Problemverfolgung.
Empfehlungen für Sie
- Hinweis: Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Makrobenchmark-Messwerte erfassen
- Baseline-Profile erstellen {:#creating-profile-rules}
- Analyse mit der Macrobenchmark-Bibliothek automatisieren {:#measuring-optimization}