Aby dowiedzieć się, jak używać biblioteki Microbenchmark, wprowadzając zmiany w kodzie aplikacji, zapoznaj się z sekcją Szybki start. Aby dowiedzieć się, jak przeprowadzić pełną konfigurację z bardziej skomplikowanymi zmianami w bazie kodu, zapoznaj się z sekcją Pełna konfiguracja projektu.
Krótkie wprowadzenie
Z tej sekcji dowiesz się, jak wypróbować testy porównawcze i przeprowadzić jednorazowe pomiary bez konieczności przenoszenia kodu do modułów. Aby uzyskać dokładne wyniki dotyczące skuteczności, wykonaj te czynności, wyłączając debugowanie w aplikacji. Zachowaj te zmiany w lokalnej kopii roboczej, nie zatwierdzając ich w systemie kontroli źródła.
Aby przeprowadzić jednorazowe testy porównawcze:
Dodaj bibliotekę do pliku
build.gradlelubbuild.gradle.ktsmodułu:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Groovy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Użyj zależności
implementationzamiast zależnościandroidTestImplementation. Jeśli używaszandroidTestImplementation, testy porównawcze nie działają, ponieważ manifest biblioteki nie jest scalany z manifestem aplikacji.Zaktualizuj typ kompilacji
debug, aby nie można było jej debugować:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Zmień
testInstrumentationRunnernaAndroidBenchmarkRunner:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Groovy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Aby dodać test porównawczy, dodaj instancję
BenchmarkRulew pliku testowym w kataloguandroidTest. Więcej informacji o pisaniu testów porównawczych znajdziesz w artykule Tworzenie klasy mikropomiarów.Poniższy fragment kodu pokazuje, jak dodać test porównawczy do testu z instrumentacją:
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() ); } } }
Aby dowiedzieć się, jak napisać test porównawczy, przejdź do sekcji Tworzenie klasy Microbenchmark.
Pełna konfiguracja projektu
Aby skonfigurować regularne porównywanie wyników, a nie jednorazowe, wyodrębnij porównania do osobnego modułu. Dzięki temu ich konfiguracja, np. ustawienie debuggable na false, jest oddzielona od zwykłych testów.
Mikrotesty uruchamiają Twój kod bezpośrednio, więc umieść kod, który chcesz przetestować, w osobnym module Gradle i ustaw zależność od tego modułu zgodnie z rysunkiem 1.
:app, :microbenchmark i :benchmarkable, która umożliwia testom Microbenchmark testowanie kodu w module :benchmarkable.Aby dodać nowy moduł Gradle, możesz użyć kreatora modułów w Android Studio. Kreator tworzy moduł wstępnie skonfigurowany do testów porównawczych, z dodanym katalogiem testów porównawczych i ustawioną wartością debuggable na false.
W Android Studio kliknij prawym przyciskiem myszy projekt lub moduł w panelu Projekt i wybierz Nowy > Moduł.
W panelu Szablony kliknij Analiza porównawcza.
Jako typ modułu testu porównawczego wybierz Mikrotest porównawczy.
Jako nazwę modułu wpisz „microbenchmark”.
Kliknij Zakończ.
Po utworzeniu modułu zmień jego plik build.gradle lub build.gradle.kts i dodaj androidTestImplementation do modułu zawierającego kod, który ma być testowany:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Tworzenie klasy mikropomiaru
Testy porównawcze to standardowe testy z instrumentacją. Aby utworzyć test porównawczy, użyj klasy BenchmarkRule udostępnianej przez bibliotekę. Do testów porównawczych aktywności używaj wartości ActivityScenario lub ActivityScenarioRule. Aby porównać kod interfejsu, użyj @UiThreadTest.
Poniższy kod przedstawia przykładowy test porównawczy:
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(); } } }
Wyłączanie czasu konfiguracji
Możesz wyłączyć pomiar czasu w przypadku fragmentów kodu, których nie chcesz mierzyć za pomocą bloku runWithTimingDisabled{}. Te sekcje zwykle zawierają kod, który musisz uruchomić w każdej iteracji testu porównawczego.
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)); }
Staraj się minimalizować ilość pracy wykonywanej w bloku measureRepeated i w runWithTimingDisabled. Blok measureRepeated jest wykonywany wielokrotnie i może mieć wpływ na ogólny czas potrzebny do przeprowadzenia testu porównawczego. Jeśli chcesz zweryfikować niektóre wyniki testu porównawczego, możesz potwierdzić ostatni wynik zamiast robić to w każdej iteracji testu.
Przeprowadź test porównawczy
W Android Studio uruchom test porównawczy tak samo jak każdy inny @Test, korzystając z działania na marginesie obok klasy lub metody testowej, jak pokazano na rysunku 3.
Możesz też uruchomić wszystkie testy z określonego modułu Gradle z wiersza poleceń, wpisując to polecenie: connectedCheck.
./gradlew benchmark:connectedChecklub pojedynczy test:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWorkWyniki testu porównawczego
Po pomyślnym uruchomieniu testu porównawczego na poziomie mikro dane są wyświetlane bezpośrednio w Android Studio, a pełny raport z testu porównawczego zawierający dodatkowe dane i informacje o urządzeniu jest dostępny w formacie JSON.
Raporty JSON i wszelkie ślady profilowania są też automatycznie kopiowane z urządzenia na hosta. Są one zapisywane na hoście w tym miejscu:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Domyślnie raport JSON jest zapisywany na urządzeniu w zewnętrznym folderze multimediów udostępnionych pakietu APK testu, który zwykle znajduje się w lokalizacji /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json.
Błędy konfiguracji
Biblioteka wykrywa te warunki, aby mieć pewność, że projekt i środowisko są skonfigurowane pod kątem dokładności danych o skuteczności:
- Wartość opcji Debuggable to
false. - Używasz urządzenia fizycznego – emulatory nie są obsługiwane.
- Zegary są blokowane, jeśli urządzenie ma dostęp do roota.
- Wystarczający poziom naładowania baterii urządzenia (co najmniej 25%).
Jeśli którykolwiek z powyższych testów zakończy się niepowodzeniem, test porównawczy zgłosi błąd, aby zniechęcić do dokonywania niedokładnych pomiarów.
Aby pominąć określone typy błędów jako ostrzeżenia i zapobiec zatrzymaniu testu porównawczego, przekaż typ błędu w rozdzielonej przecinkami liście do argumentu instrumentacji androidx.benchmark.suppressErrors.
Możesz to ustawić w skrypcie Gradle, jak pokazano w tym przykładzie:
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Groovy
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Możesz też pominąć błędy z poziomu wiersza poleceń:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
Pomijanie błędów umożliwia uruchomienie testu porównawczego w nieprawidłowo skonfigurowanym stanie, a wynik testu porównawczego jest celowo zmieniany przez dodanie do nazw testów przedrostka „error”. Na przykład uruchomienie testu porównawczego z możliwością debugowania z pominięciem w poprzednim fragmencie kodu spowoduje dodanie do nazw testów prefiksu DEBUGGABLE_.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony.
- Tworzenie testu Macrobenchmark
- Tworzenie mikrotestów porównawczych bez Gradle
- Tworzenie profili podstawowych {:#creating-profile-rules}