Biblioteki Macrobenchmark używaj do testowania większych przypadków użycia aplikacji, w tym uruchamiania aplikacji i złożonych manipulacji interfejsem, takich jak przewijanie RecyclerView
lub uruchamianie animacji. Jeśli chcesz testować mniejsze obszary kodu, zapoznaj się z informacjami o bibliotece Microbenchmark. Na tej stronie dowiesz się, jak skonfigurować bibliotekę Macrobenchmark.
Biblioteka zapisuje wyniki testów porównawczych w konsoli Android Studio i w pliku JSON zawierającym więcej szczegółów. Udostępnia też pliki śledzenia, które możesz wczytać i analizować w Android Studio.
Używaj biblioteki Macrobenchmark w środowisku ciągłej integracji (CI), zgodnie z opisem w artykule Benchmark w trybie ciągłej integracji.
Za pomocą biblioteki Macrobenchmark możesz generować profile bazowe. Najpierw skonfiguruj bibliotekę Macrobenchmark, a potem możesz utworzyć profil Baseline.
Konfigurowanie projektu
Zalecamy używanie Macrobenchmark z najnowszą wersją Androida Studio, aby korzystać z funkcji IDE zintegrowanych z Macrobenchmark.
Konfigurowanie modułu Macrobenchmark
Testy makro wymagają modułu
com.android.test
– oddzielonego od kodu aplikacji – który odpowiada za uruchamianie testów
mierzących wydajność aplikacji.
W Android Studio dostępny jest szablon, który upraszcza konfigurację modułu Macrobenchmark. Szablon modułu testów porównawczych automatycznie tworzy w projekcie moduł do pomiaru aplikacji utworzonej przez moduł aplikacji, w tym przykładowy test porównawczy uruchamiania.
Aby utworzyć nowy moduł za pomocą szablonu modułu:
W panelu Projekt w Android Studio kliknij prawym przyciskiem myszy projekt lub moduł i wybierz Nowy > Moduł.
W panelu Szablony kliknij Analiza porównawcza. Możesz dostosować aplikację docelową, czyli aplikację, która ma być testowana, a także nazwę pakietu i modułu nowego modułu Macrobenchmark.
Kliknij Zakończ.
Rysunek 1. Szablon modułu porównawczego.
Konfigurowanie aplikacji
Aby przeprowadzić test porównawczy aplikacji, która jest celem testu Macrobenchmark, musi ona być profileable
, co umożliwia odczytywanie szczegółowych informacji o śledzeniu bez wpływu na wydajność. Kreator modułu automatycznie dodaje tag <profileable>
do pliku AndroidManifest.xml
aplikacji.
Upewnij się, że aplikacja docelowa zawiera wersję ProfilerInstaller
1.3 lub nowszą, która jest wymagana przez bibliotekę Macrobenchmark do włączania rejestrowania profili, resetowania i czyszczenia pamięci podręcznej shaderów.
Skonfiguruj aplikację testową tak, aby była jak najbardziej zbliżona do wersji produkcyjnej. Skonfiguruj go jako niedający się debugować i najlepiej z włączoną minimalizacją, co poprawia wydajność. Zwykle polega to na utworzeniu kopii wersji, która działa tak samo, ale jest podpisywana lokalnie za pomocą kluczy debugowania.
Możesz też użyć initWith
, aby zlecić to Gradle:
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 { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) // In real app, this would use its own release keystore signingConfig = signingConfigs.getByName("debug") } }
Aby mieć pewność, że test porównawczy tworzy i testuje prawidłową odmianę aplikacji (jak pokazano na rysunku 2), wykonaj te czynności:
- Przeprowadź synchronizację Gradle.
- Otwórz panel Warianty kompilacji.
- Wybierz wariant testu porównawczego zarówno aplikacji, jak i modułu Macrobenchmark.
Rysunek 2. Wybierz wariant referencyjny.
(Opcjonalnie) Konfigurowanie aplikacji wielomodułowej
Jeśli Twoja aplikacja ma więcej niż 1 moduł Gradle, upewnij się, że skrypty kompilacji wiedzą, który wariant kompilacji należy skompilować. Dodaj właściwośćmatchingFallbacks
do typu kompilacjibenchmark
modułów :macrobenchmark
i :app
. Pozostałe moduły Gradle mogą mieć taką samą konfigurację jak wcześniej.
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") }
Groovy
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
Bez tego nowo dodany typ kompilacji benchmark
spowoduje niepowodzenie kompilacji i wyświetlenie tego komunikatu o błędzie:
> Could not resolve project :shared.
Required by:
project :app
> No matching variant of project :shared was found.
...
Podczas wybierania wariantów kompilacji w projekcie wybierz benchmark
w przypadku modułów :app
i :macrobenchmark
oraz release
w przypadku wszystkich innych modułów w aplikacji, jak pokazano na rysunku 3:
Rysunek 3. Warianty testów porównawczych w przypadku projektu wielomodułowego z wybranymi typami kompilacji wydania i testu porównawczego.
Więcej informacji znajdziesz w artykule Korzystanie z zarządzania zależnościami z uwzględnieniem wariantów.
(Opcjonalnie) Konfigurowanie wersji produktów
Jeśli w aplikacji masz skonfigurowanych kilka wersji produktu, skonfiguruj moduł :macrobenchmark
, aby wiedział, którą wersję aplikacji ma tworzyć i w stosunku do której ma przeprowadzać testy porównawcze.
Przykłady na tej stronie korzystają z 2 wersji produktu w :app
module: demo
i production
, jak pokazano w tym fragmencie kodu:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
Bez tej konfiguracji może pojawić się błąd kompilacji podobny do tego, który występuje w przypadku wielu modułów Gradle:
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:
...
W 2 sekcjach poniżej znajdziesz sposoby konfigurowania testów porównawczych z użyciem wielu wersji produktu.
Używanie parametru missingDimensionStrategy
Określenie missingDimensionStrategy
w defaultConfig
modułu :macrobenchmark
informuje system kompilacji, że ma użyć wymiaru wersji. Określ, których wymiarów chcesz używać, jeśli nie znajdziesz ich w module.
W poniższym przykładzie production
smak jest używany jako domyślny wymiar:
Kotlin
defaultConfig { missingDimensionStrategy("environment", "production") }
Groovy
defaultConfig { missingDimensionStrategy "environment", "production" }
Dzięki temu moduł :macrobenchmark
może tworzyć i testować tylko określony wariant produktu, co jest przydatne, jeśli wiesz, że tylko jeden wariant produktu ma odpowiednią konfigurację do przeprowadzenia testu porównawczego.
Definiowanie wersji produktu w module :macrobenchmark
Jeśli chcesz tworzyć i porównywać inne wersje produktu, zdefiniuj je w module :macrobenchmark
. Określ go podobnie jak w module :app
, ale przypisz tylko productFlavors
do dimension
. Nie są wymagane żadne inne ustawienia:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
Po zdefiniowaniu i zsynchronizowaniu projektu wybierz odpowiedni wariant kompilacji w panelu Build Variants (Warianty kompilacji), jak pokazano na rysunku 4:
Rysunek 4. Warianty referencyjne projektu z wybranymi wersjami produktu „productionBenchmark” i „release”.
Więcej informacji znajdziesz w artykule Rozwiązywanie błędów kompilacji związanych z dopasowywaniem wariantów.
Tworzenie klasy makrobenchmarku
Testy porównawcze są dostępne w interfejsie API reguły MacrobenchmarkRule
JUnit4 w bibliotece Macrobenchmark. Zawiera ona metodę measureRepeated
, która umożliwia określanie różnych warunków uruchamiania i testowania aplikacji docelowej.
Musisz podać co najmniej packageName
aplikacji docelowej, rodzaj metrics
, który chcesz zmierzyć, oraz liczbę iterations
, które musi wykonać test porównawczy.
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, setupBlock = { // Press home button before each run to ensure the starting activity isn't visible. pressHome() } ) { // starts default launch activity startActivityAndWait() } }
Java
@LargeTest @RunWith(AndroidJUnit4.class) public class SampleStartupBenchmark { @Rule public MacrobenchmarkRule benchmarkRule = new MacrobenchmarkRule(); @Test public void startup() { benchmarkRule.measureRepeated( /* packageName */ TARGET_PACKAGE, /* metrics */ Arrays.asList(new StartupTimingMetric()), /* iterations */ 5, /* measureBlock */ scope -> { // starts default launch activity scope.startActivityAndWait(); return Unit.INSTANCE; } ); } }
Wszystkie opcje dostosowywania testu porównawczego znajdziesz w sekcji Dostosowywanie testów porównawczych.
Przeprowadź test porównawczy
Przeprowadź test w Android Studio, aby zmierzyć wydajność aplikacji na urządzeniu. Testy porównawcze możesz uruchamiać tak samo jak inne testy@Test
, korzystając z działania w rowie obok klasy lub metody testowej, jak pokazano na rysunku 5.
Rysunek 5. Uruchom makrobenchmark z działaniem w rowie obok klasy testu.
Możesz też uruchomić wszystkie testy porównawcze w module Gradle z wiersza poleceń, wykonując polecenie connectedCheck
:
./gradlew :macrobenchmark:connectedCheck
Możesz uruchomić pojedynczy test, wykonując to polecenie:
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup
Więcej informacji o uruchamianiu i monitorowaniu testów porównawczych w trybie ciągłej integracji znajdziesz w artykule Testy porównawcze w trybie ciągłej integracji.
Wyniki testu porównawczego
Po pomyślnym uruchomieniu testu porównawczego dane są wyświetlane bezpośrednio w Android Studio i zapisywane w pliku JSON do wykorzystania w integracji ciągłej. Każda zmierzona iteracja rejestruje oddzielny ślad systemu. Wyniki śledzenia możesz otworzyć, klikając linki w panelu Wyniki testu, jak pokazano na ilustracji 6:
Rysunek 6. Wyniki uruchamiania testu porównawczego na poziomie makro.
Po wczytaniu śladu Android Studio wyświetli prośbę o wybranie procesu do analizy. Wybór jest wstępnie wypełniony procesem aplikacji docelowej, jak pokazano na rysunku 7:
Rysunek 7. Wybór procesu śledzenia w Studio.
Po wczytaniu pliku śledzenia Studio wyświetli wyniki w profilerze procesora:
Rysunek 8. Śledzenie w Studio.
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/
Ręczne uzyskiwanie dostępu do plików śledzenia
Jeśli chcesz użyć narzędzia Perfetto do analizy pliku śledzenia, musisz wykonać dodatkowe czynności. Perfetto umożliwia sprawdzanie wszystkich procesów zachodzących na urządzeniu podczas śledzenia, a profiler CPU w Android Studio ogranicza sprawdzanie do jednego procesu.
Jeśli wywołasz testy z Androida Studio lub z wiersza poleceń Gradle, pliki śledzenia zostaną automatycznie skopiowane z urządzenia na hosta. Są one zapisywane na hoście w tej lokalizacji:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
Gdy plik śledzenia będzie już na komputerze hosta, możesz go otworzyć w Android Studio, wybierając w menu File > Open (Plik > Otwórz). Wyświetla widok narzędzia profilującego pokazany w poprzedniej sekcji.
Błędy konfiguracji
Jeśli aplikacja jest nieprawidłowo skonfigurowana (można ją debugować lub nie można jej profilować), Macrobenchmark zwraca błąd zamiast podawać nieprawidłowe lub niekompletne pomiary. Możesz pominąć te błędy za pomocą argumentu androidx.benchmark.suppressErrors
.
Testy porównawcze na poziomie makro zwracają też błędy podczas próby pomiaru na emulatorze lub na urządzeniu z niskim poziomem baterii, co może negatywnie wpływać na dostępność rdzeni i szybkość zegara.
Dostosowywanie punktów odniesienia
Funkcja measureRepeated
akceptuje różne parametry, które wpływają na to, jakie dane zbiera biblioteka, jak uruchamiana i kompilowana jest aplikacja oraz ile iteracji wykonuje test.
Zbieranie danych
Dane to główny rodzaj informacji wyodrębnianych z testów porównawczych. Dostępne są te dane:
Więcej informacji o danych znajdziesz w artykule Zbieranie danych testu porównawczego na poziomie makro.
Ulepszanie danych śledzenia za pomocą zdarzeń niestandardowych
Warto dodać do aplikacji niestandardowe zdarzenia śledzenia, które będą widoczne w raporcie śledzenia i pomogą wskazać problemy specyficzne dla Twojej aplikacji. Więcej informacji o tworzeniu niestandardowych zdarzeń śledzenia znajdziesz w artykule Definiowanie zdarzeń niestandardowych.
CompilationMode
Testy porównawcze mogą określać CompilationMode
, który definiuje, jaka część aplikacji musi być wstępnie skompilowana z kodu bajtowego DEX (format kodu bajtowego w pliku APK) do kodu maszynowego (podobnego do wstępnie skompilowanego kodu C++).
Domyślnie testy Macrobenchmark są uruchamiane z parametrem CompilationMode.DEFAULT
, który instaluje profil podstawowy (jeśli jest dostępny) na Androidzie 7 (API na poziomie 24) i nowszym.
Jeśli używasz Androida 6 (poziom interfejsu API 23) lub starszego, domyślnym zachowaniem systemu jest pełna kompilacja pliku APK.
Profil podstawowy możesz zainstalować, jeśli aplikacja docelowa zawiera zarówno profil podstawowy, jak i bibliotekę ProfileInstaller
.
Na Androidzie 7 i nowszym możesz dostosować CompilationMode
, aby wpływać na ilość wstępnej kompilacji na urządzeniu i symulować różne poziomy kompilacji AOT (ahead-of-time) lub buforowania JIT. Zobacz CompilationMode.Full
, CompilationMode.Partial
, CompilationMode.None
i CompilationMode.Ignore
.
Ta funkcja jest oparta na poleceniach kompilacji ART. Każdy test porównawczy czyści dane profilu przed rozpoczęciem, aby zapewnić brak zakłóceń między testami.
StartupMode
Aby rozpocząć aktywność, możesz przekazać wstępnie zdefiniowany tryb uruchamiania: COLD
, WARM
lub HOT
. Ten parametr zmienia sposób uruchamiania aktywności i stan procesu na początku testu.
Więcej informacji o rodzajach uruchamiania znajdziesz w artykule Czas uruchamiania aplikacji.
Próbki
Przykładowy projekt jest dostępny w przykładzie Macrobenchmark w repozytorium na GitHubie.
Prześlij opinię
Aby zgłosić problemy lub przesłać prośby o dodanie funkcji do biblioteki Jetpack Macrobenchmark, skorzystaj z publicznego narzędzia do śledzenia problemów.
Polecane dla Ciebie
- Uwaga: tekst linku jest wyświetlany, gdy JavaScript jest wyłączony.
- Zbieranie danych testu porównawczego Macrobenchmark
- Tworzenie profili podstawowych {:#creating-profile-rules}
- Automatyzowanie pomiarów za pomocą biblioteki Macrobenchmark {:#measuring-optimization}