Informationen dazu, wie Sie die Microbenchmark-Bibliothek verwenden, indem Sie Änderungen am Anwendungscode vornehmen, finden Sie im Abschnitt Schnellstart. Informationen zum Durchführen einer vollständigen Einrichtung mit komplexeren Änderungen an der Codebasis finden Sie im Abschnitt Vollständige Projekteinrichtung.
Kurzanleitung
In diesem Abschnitt erfahren Sie, wie Sie Benchmarking ausprobieren und einmalige Messungen ausführen, ohne Code in Module verschieben zu müssen. Um genaue Leistungsergebnisse zu erhalten, muss bei diesen Schritten die Fehlerbehebung in Ihrer Anwendung deaktiviert werden. Bewahren Sie dies daher in einer lokalen funktionierenden Kopie auf, ohne die Änderungen in Ihr Versionsverwaltungssystem zu übernehmen.
So führen Sie einen einmaligen Benchmark durch:
Fügen Sie die Bibliothek der Datei
build.gradle
oderbuild.gradle.kts
Ihres Moduls hinzu:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Groovy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Verwenden Sie eine
implementation
-Abhängigkeit anstelle einerandroidTestImplementation
-Abhängigkeit. Wenn SieandroidTestImplementation
verwenden, werden die Benchmarks nicht ausgeführt, da das Manifest der Bibliothek nicht in das App-Manifest eingefügt wurde.Aktualisieren Sie den
debug
-Buildtyp so, dass er nicht debugbar ist:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Ändern Sie
testInstrumentationRunner
inAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Cool
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Fügen Sie eine Instanz von
BenchmarkRule
in einer Testdatei im VerzeichnisandroidTest
hinzu, um den Benchmark hinzuzufügen. Weitere Informationen zum Erstellen von Benchmarks finden Sie unter Microbenchmark-Klasse erstellen.Das folgende Code-Snippet zeigt, wie Sie einem instrumentierten Test einen Benchmark hinzufügen:
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { BenchmarkRuleKt.measureRepeated( (Function1<BenchmarkRule.Scope, Unit>) scope -> doSomeWork() ); } } }
Informationen zum Erstellen eines Benchmarks finden Sie unter Microbenchmark-Klasse erstellen.
Vollständige Projekteinrichtung
Wenn Sie regelmäßige statt einmalige Benchmarks einrichten möchten, trennen Sie die Benchmarks in ein eigenes Modul. So wird sichergestellt, dass die Konfiguration, z. B. die Einstellung von debuggable
auf false
, von regulären Tests getrennt ist.
Da Microbenchmark Ihren Code direkt ausführt, platzieren Sie den Code, den Sie benchmarken möchten, in einem separaten Gradle-Modul und legen Sie die Abhängigkeit von diesem Modul fest, wie in Abbildung 1 dargestellt.
Wenn Sie ein neues Gradle-Modul hinzufügen möchten, können Sie den Modulassistenten in Android Studio verwenden. Der Assistent erstellt ein Modul, das für Benchmarks vorkonfiguriert ist. Es wird ein Benchmark-Verzeichnis hinzugefügt und debuggable
auf false
festgelegt.
Klicken Sie in Android Studio im Bereich Project (Projekt) mit der rechten Maustaste auf Ihr Projekt oder Modul und dann auf New > Module (Neu > Modul).
Wählen Sie im Bereich Templates (Vorlagen) die Option Benchmark aus.
Wählen Sie als Typ des Benchmark-Moduls MicroBenchmark aus.
Geben Sie „microbenchmark“ als Modulnamen ein.
Klicken Sie auf Fertig.
Ändern Sie nach dem Erstellen des Moduls die Datei build.gradle
oder build.gradle.kts
und fügen Sie dem Modul, das den Code für das Benchmark enthält, androidTestImplementation
hinzu:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Microbenchmark-Klasse erstellen
Benchmarks sind standardmäßige Instrumentierungstests. Verwenden Sie zum Erstellen eines Benchmarks die von der Bibliothek bereitgestellte Klasse BenchmarkRule
. Verwenden Sie ActivityScenario
oder ActivityScenarioRule
, um Aktivitäten zu vergleichen. Verwenden Sie @UiThreadTest
, um den UI-Code zu benchmarken.
Der folgende Code zeigt einen Beispiel-Benchmark:
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { final BenchmarkState state = benchmarkRule.getState(); while (state.keepRunning()) { doSomeWork(); } } }
Zeitplan für die Einrichtung deaktivieren
Mit dem runWithTimingDisabled{}
-Block können Sie das Timing für Codeabschnitte deaktivieren, die Sie nicht messen möchten. Diese Abschnitte enthalten in der Regel Code, den Sie bei jeder Iteration des Benchmarks ausführen müssen.
Kotlin
// using random with the same seed, so that it generates the same data every run private val random = Random(0) // create the array once and just copy it in benchmarks private val unsorted = IntArray(10_000) { random.nextInt() } @Test fun benchmark_quickSort() { // ... benchmarkRule.measureRepeated { // copy the array with timing disabled to measure only the algorithm itself listToSort = runWithTimingDisabled { unsorted.copyOf() } // sort the array in place and measure how long it takes SortingAlgorithms.quickSort(listToSort) } // assert only once not to add overhead to the benchmarks assertTrue(listToSort.isSorted) }
Java
private final int[] unsorted = new int[10000]; public SampleBenchmark() { // Use random with the same seed, so that it generates the same data every // run. Random random = new Random(0); // Create the array once and copy it in benchmarks. Arrays.setAll(unsorted, (index) -> random.nextInt()); } @Test public void benchmark_quickSort() { final BenchmarkState state = benchmarkRule.getState(); int[] listToSort = new int[0]; while (state.keepRunning()) { // Copy the array with timing disabled to measure only the algorithm // itself. state.pauseTiming(); listToSort = Arrays.copyOf(unsorted, 10000); state.resumeTiming(); // Sort the array in place and measure how long it takes. SortingAlgorithms.quickSort(listToSort); } // Assert only once, not to add overhead to the benchmarks. assertTrue(SortingAlgorithmsKt.isSorted(listToSort)); }
Versuchen Sie, den Arbeitsaufwand innerhalb des measureRepeated
-Blocks und von runWithTimingDisabled
zu minimieren. Der Block measureRepeated
wird mehrmals ausgeführt und kann sich auf die Gesamtzeit auswirken, die für die Ausführung des Benchmarks erforderlich ist. Wenn Sie einige Ergebnisse eines Benchmarks prüfen möchten, können Sie das letzte Ergebnis prüfen, anstatt dies bei jeder Iteration des Benchmarks zu tun.
Benchmark ausführen
Führen Sie in Android Studio Ihre Benchmark wie bei jeder @Test
aus. Verwenden Sie dazu die Gutter-Aktion neben der Testklasse oder -methode, wie in Abbildung 3 gezeigt.
Alternativ können Sie in der Befehlszeile connectedCheck
ausführen, um alle Tests aus dem angegebenen Gradle-Modul auszuführen:
./gradlew benchmark:connectedCheck
Oder für einen einzelnen Test:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Benchmark-Ergebnisse
Nach einem erfolgreichen Microbenchmark-Lauf werden die Messwerte direkt in Android Studio angezeigt und ein vollständiger Benchmarkbericht mit zusätzlichen Messwerten und Geräteinformationen ist im JSON-Format verfügbar.
JSON-Berichte und alle Profiling-Traces werden ebenfalls automatisch vom Gerät auf den Host kopiert. Sie werden an folgendem Ort auf dem Hostcomputer geschrieben:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Standardmäßig wird der JSON-Bericht auf dem Gerät im externen freigegebenen Medienordner des Test-APKs auf die Festplatte geschrieben. Dieser Ordner befindet sich normalerweise unter /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Konfigurationsfehler
Die Bibliothek erkennt die folgenden Bedingungen, um sicherzustellen, dass Ihr Projekt und Ihre Umgebung für Release-genaue Leistung eingerichtet sind:
- „Debuggable“ ist auf
false
festgelegt. - Es wird ein physisches Gerät verwendet. Emulatoren werden nicht unterstützt.
- Die Uhren sind gesperrt, wenn das Gerät gerootet ist.
- Der Akkustand des Geräts muss mindestens 25 % betragen.
Wenn eine der vorherigen Prüfungen fehlschlägt, meldet der Benchmark einen Fehler, um ungenaue Messungen zu vermeiden.
Wenn Sie bestimmte Fehlertypen als Warnungen unterdrücken und verhindern möchten, dass der Benchmark dadurch beendet wird, übergeben Sie den Fehlertyp in einer durch Kommas getrennten Liste an das Instrumentierungsargument androidx.benchmark.suppressErrors
.
Sie können dies in Ihrem Gradle-Script festlegen, wie im folgenden Beispiel gezeigt:
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Groovy
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Sie können Fehler auch über die Befehlszeile unterdrücken:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
Wenn Sie Fehler unterdrücken, wird die Benchmark in einem falsch konfigurierten Zustand ausgeführt. Die Ausgabe der Benchmark wird bewusst umbenannt, indem Testnamen mit dem Fehler vorangestellt werden. Wenn Sie beispielsweise einen debuggbaren Benchmark mit der Unterdrückung im vorherigen Snippet ausführen, wird den Testnamen DEBUGGABLE_
vorangestellt.
Empfehlungen für dich
- Hinweis: Der Linktext wird angezeigt, wenn JavaScript deaktiviert ist.
- Makrobenchmark schreiben
- Microbenchmarks ohne Gradle erstellen
- Baseline-Profile erstellen {:#creating-profile-rules}