Aby dowiedzieć się, jak korzystać z biblioteki Microbenchmark, wprowadzając zmiany w kodzie aplikacji, zapoznaj się z sekcją Krótkie wprowadzenie. Aby dowiedzieć się, jak przeprowadzić pełną konfigurację z bardziej skomplikowanymi zmianami w kodzie, przeczytaj sekcję Pełna konfiguracja projektu.
Krótkie wprowadzenie
Z tej sekcji dowiesz się, jak przeprowadzić test porównawczy i jednorazowe pomiary bez konieczności przenoszenia kodu do modułów. Aby uzyskać dokładne wyniki dotyczące wydajności, wykonaj te czynności, które obejmują wyłączenie debugowania w aplikacji. Dlatego zachowaj lokalną kopię roboczą bez zatwierdzania zmian w systemie kontroli wersji.
Aby przeprowadzić jednorazową analizę porównawczą:
Dodaj bibliotekę do pliku
build.gradle
lubbuild.gradle.kts
modułu:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Odlotowe
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Użyj zależności
implementation
zamiastandroidTestImplementation
zależności. Jeśli korzystasz z metodyandroidTestImplementation
, testy porównawcze nie będą jest uruchamiane, ponieważ biblioteka manifest nie jest zintegrowana z aplikacją. pliku manifestu.Zmień typ kompilacji
debug
, aby nie można było go debugować:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Zmień
testInstrumentationRunner
naAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Groovy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Dodaj wystąpienie
BenchmarkRule
w pliku testowym w plikuandroidTest
, aby dodać test porównawczy. Więcej informacji o tworzeniu testów porównawczych znajdziesz w artykule Tworzenie klasy testów mikroporównawczych.Ten fragment kodu pokazuje, jak dodać punkt odniesienia do testu z użyciem pomiarów:
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 testów mikroporównawczych.
Pełna konfiguracja projektu
Aby skonfigurować regularne testy porównawcze, a nie jednorazowe,
analizy porównawcze w osobnym module. Dzięki temu ich konfiguracja, np. ustawienie debuggable
na false
, jest oddzielona od zwykłych testów.
Test porównawczy uruchamia Twój kod bezpośrednio, więc umieść kod, który chcesz testów porównawczych w osobnym module Gradle i ustaw zależność od tego modułu jako co pokazano na ilustracji 1.
Aby dodać nowy moduł Gradle, możesz użyć kreatora modułów w Android Studio.
tworzy moduł skonfigurowany wstępnie do testów porównawczych,
dodano katalog testu porównawczego i ustawienie debuggable
na false
.
W panelu Projekt w Android Studio kliknij prawym przyciskiem myszy projekt lub moduł, a potem wybierz Nowy > Moduł.
W panelu Szablony wybierz Analiza porównawcza.
Jako typ modułu testu porównawczego wybierz Microbenchmark.
Wpisz „microbenchmark” dla nazwy modułu.
Kliknij Zakończ.
Po utworzeniu modułu zmień jego plik build.gradle
lub build.gradle.kts
i dodaj do modułu zawierającego kod do testów porównawczych element androidTestImplementation
:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Tworzenie zajęć z mikrobenchmarkami
Wskaźniki to standardowe testy z wykorzystaniem instrumentacji. Aby utworzyć punkt odniesienia, użyj klasy BenchmarkRule
udostępnionej przez bibliotekę. Aby porównać aktywności, użyj funkcji
ActivityScenario
lub ActivityScenarioRule
. Aby porównać kod interfejsu,
użyj @UiThreadTest
.
Poniższy kod pokazuje przykładowe testy porównawcze:
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łącz czas konfiguracji
Możesz wyłączyć czas w sekcjach kodu, których nie chcesz mierzyć za pomocą funkcji
Blokuj runWithTimingDisabled{}
. Te sekcje zwykle reprezentują kod, który musisz uruchomić w przypadku 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)); }
Postaraj się zminimalizować ilość pracy wykonywanej wewnątrz bloku measureRepeated
i w środku runWithTimingDisabled
. Blok measureRepeated
jest wykonywany wielokrotnie i może wpływać na łączny czas potrzebny do przeprowadzenia testu porównawczego. Jeśli
Musisz zweryfikować
jakieś wyniki testu porównawczego, możesz wskazać ostatni wynik
zamiast przy każdej
wersji testu porównawczego.
Przeprowadzanie testu porównawczego
W Android Studio przeprowadź test porównawczy tak samo jak w przypadku dowolnego @Test
, używając
działania rynien obok klasy lub metody testowej, jak to widać na rysunku 3.
Możesz też z poziomu wiersza poleceń uruchomić connectedCheck
, aby uruchomić wszystkie polecenia
testów z określonego modułu Gradle:
./gradlew benchmark:connectedCheck
Lub pojedynczy test:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Wyniki testu porównawczego
Po pomyślnym uruchomieniu mikrotestu dane są wyświetlane bezpośrednio w Android Studio, a pełny raport testów porównawczych z dodatkowymi danymi i informacjami o urządzeniu jest dostępny w formacie JSON.
Raporty JSON i wszystkie ślady profilowania są również automatycznie kopiowane z urządzenia . Są one zapisywane na hoście w tej lokalizacji:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Domyślnie raport w formacie JSON jest zapisywany na dysku urządzenia w zewnętrznym folderze udostępnionych multimediów pliku APK testowego, który zwykle znajduje się w folderze /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Błędy konfiguracji
Biblioteka wykrywa te warunki, aby zapewnić, że projekt i środowisko są skonfigurowane pod kątem dokładnej wydajności w wersji:
- Pole „Możliwość debugowania” ma wartość
false
. - Używane jest urządzenie fizyczne – emulatory nie są obsługiwane.
- Jeśli urządzenie jest zrootowane, zegary są zablokowane.
- Urządzenie musi mieć co najmniej 25% poziom naładowania baterii.
Jeśli któraś z wcześniejszych kontroli zakończy się niepowodzeniem, test porównawczy zgłosi błąd, aby zniechęcaj do niedokładnych pomiarów.
Aby ukryć określone typy błędów jako ostrzeżenia i uniemożliwić im zatrzymanie
testu porównawczego, przekaż typ błędu do instrumentacji w postaci listy rozdzielanej przecinkami
argument 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" } }
Odlotowe
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Możesz też pominąć błędy przy użyciu wiersza poleceń:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
Pomijanie błędów umożliwia uruchomienie testu w nieprawidłowo skonfigurowanym stanie, a wynik testu jest celowo przemianowany przez dodanie do nazwy testu błędu. Na przykład uruchomienie testu porównawczego z możliwością debugowania z wyłączeniem w poprzednim fragmencie kodu powoduje, że nazwy testów mają przedrostek DEBUGGABLE_
.
Polecane dla Ciebie
- Uwaga: tekst linku wyświetla się, gdy JavaScript jest wyłączony
- Tworzenie testu porównawczego makro
- Tworzenie mikrobenchmarków bez Gradle
- Tworzenie profili podstawowych {:#Creation-profile-rules}