W tym dokumencie znajdziesz sprawdzone metody i instrukcje rozwiązywania problemów, które pomogą Ci zdiagnozować problemy i upewnić się, że profile podstawowe działają prawidłowo i przynoszą jak największe korzyści.
Problemy z kompilacją
Jeśli skopiujesz przykład profili bazowych z aplikacji przykładowej Now in Android, podczas wykonywania zadania związanego z profilami bazowymi możesz napotkać błędy testów, które wskazują, że testów nie można uruchomić na emulatorze:
./gradlew assembleDemoRelease
Starting a Gradle Daemon (subsequent builds will be faster)
Calculating task graph as no configuration cache is available for tasks: assembleDemoRelease
Type-safe project accessors is an incubating feature.
> Task :benchmarks:pixel6Api33DemoNonMinifiedReleaseAndroidTest
Starting 14 tests on pixel6Api33
com.google.samples.apps.nowinandroid.foryou.ScrollForYouFeedBenchmark > scrollFeedCompilationNone[pixel6Api33] FAILED
java.lang.AssertionError: ERRORS (not suppressed): EMULATOR
WARNINGS (suppressed):
...
Błędy występują, ponieważ aplikacja Now in Android używa urządzenia zarządzanego przez Gradle do generowania profilu podstawowego. Błędy są oczekiwane, ponieważ zwykle nie należy uruchamiać testów wydajności na emulatorze. Jednak ponieważ podczas generowania profili podstawowych nie zbierasz danych o skuteczności, możesz dla wygody uruchamiać zbieranie profili podstawowych na emulatorach. Aby używać profili podstawowych z emulatorem, przeprowadź kompilację i instalację z poziomu wiersza poleceń i ustaw argument, aby włączyć reguły profili podstawowych:
installDemoRelease -Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=BaselineProfile
Możesz też utworzyć niestandardową konfigurację uruchamiania w Android Studio, aby włączyć profile bazowe na emulatorach. W tym celu kliknij Uruchom > Edytuj konfiguracje:
Sprawdzanie instalacji i stosowania profilu
Aby sprawdzić, czy sprawdzany plik APK lub pakiet Android App Bundle (AAB) pochodzi z wersji kompilacji, która zawiera profile bazowe:
- W Android Studio wybierz Build > Analyze APK (Utwórz > Przeanalizuj APK).
- Otwórz plik AAB lub APK.
Sprawdź, czy plik
baseline.profistnieje:- Jeśli sprawdzasz plik AAB, profil znajduje się w lokalizacji
/BUNDLE-METADATA/com.android.tools.build.profiles/baseline.prof. Jeśli sprawdzasz plik APK, profil znajduje się w tym miejscu:
/assets/dexopt/baseline.profObecność tego pliku jest pierwszym sygnałem prawidłowej konfiguracji kompilacji. Jeśli go nie ma, oznacza to, że środowisko wykonawcze Androida nie otrzyma żadnych instrukcji wstępnej kompilacji podczas instalacji.
Rysunek 2. Sprawdź profil podstawowy za pomocą narzędzia APK Analyzer w Android Studio.
- Jeśli sprawdzasz plik AAB, profil znajduje się w lokalizacji
Profile podstawowe muszą być kompilowane na urządzeniu, na którym działa aplikacja. Podczas instalowania wersji, których nie można debugować, za pomocą Android Studio lub narzędzia wiersza poleceń Gradle Wrapper kompilacja na urządzeniu odbywa się automatycznie. Jeśli zainstalujesz aplikację ze Sklepu Google Play, profile podstawowe zostaną skompilowane podczas aktualizacji urządzenia w tle, a nie w momencie instalacji. Gdy aplikacja jest instalowana za pomocą innych narzędzi, biblioteka Jetpack ProfileInstaller odpowiada za umieszczanie profili w kolejce do kompilacji podczas następnego procesu optymalizacji DEX w tle.
W takich przypadkach, jeśli chcesz mieć pewność, że używane są profile podstawowe, może być konieczne wymuszenie kompilacji profili podstawowych.
ProfileVerifier umożliwia sprawdzanie stanu instalacji i kompilacji profilu, jak pokazano w tym przykładzie:
Kotlin
private const val TAG = "MainActivity" class MainActivity : ComponentActivity() { ... override fun onResume() { super.onResume() lifecycleScope.launch { logCompilationStatus() } } private suspend fun logCompilationStatus() { withContext(Dispatchers.IO) { val status = ProfileVerifier.getCompilationStatusAsync().await() when (status.profileInstallResultCode) { RESULT_CODE_NO_PROFILE -> Log.d(TAG, "ProfileInstaller: Baseline Profile not found") RESULT_CODE_COMPILED_WITH_PROFILE -> Log.d(TAG, "ProfileInstaller: Compiled with profile") RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION -> Log.d(TAG, "ProfileInstaller: Enqueued for compilation") RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING -> Log.d(TAG, "ProfileInstaller: App was installed through Play store") RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST -> Log.d(TAG, "ProfileInstaller: PackageName not found") RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ -> Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read") RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE -> Log.d(TAG, "ProfileInstaller: Can't write cache file") RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION -> Log.d(TAG, "ProfileInstaller: Enqueued for compilation") else -> Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued") } } }
Java
public class MainActivity extends ComponentActivity { private static final String TAG = "MainActivity"; @Override protected void onResume() { super.onResume(); logCompilationStatus(); } private void logCompilationStatus() { ListeningExecutorService service = MoreExecutors.listeningDecorator( Executors.newSingleThreadExecutor()); ListenableFuture<ProfileVerifier.CompilationStatus> future = ProfileVerifier.getCompilationStatusAsync(); Futures.addCallback(future, new FutureCallback<>() { @Override public void onSuccess(CompilationStatus result) { int resultCode = result.getProfileInstallResultCode(); if (resultCode == RESULT_CODE_NO_PROFILE) { Log.d(TAG, "ProfileInstaller: Baseline Profile not found"); } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE) { Log.d(TAG, "ProfileInstaller: Compiled with profile"); } else if (resultCode == RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION) { Log.d(TAG, "ProfileInstaller: Enqueued for compilation"); } else if (resultCode == RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING) { Log.d(TAG, "ProfileInstaller: App was installed through Play store"); } else if (resultCode == RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST) { Log.d(TAG, "ProfileInstaller: PackageName not found"); } else if (resultCode == RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ) { Log.d(TAG, "ProfileInstaller: Cache file exists but cannot be read"); } else if (resultCode == RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILE) { Log.d(TAG, "ProfileInstaller: Can't write cache file"); } else if (resultCode == RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION) { Log.d(TAG, "ProfileInstaller: Enqueued for compilation"); } else { Log.d(TAG, "ProfileInstaller: Profile not compiled or enqueued"); } } @Override public void onFailure(Throwable t) { Log.d(TAG, "ProfileInstaller: Error getting installation status: " + t.getMessage()); } }, service); } }
Poniższe kody wyników zawierają wskazówki dotyczące przyczyn niektórych problemów:
RESULT_CODE_COMPILED_WITH_PROFILE- Profil jest instalowany i kompilowany, a potem używany przy każdym uruchomieniu aplikacji. To jest wynik, który chcesz zobaczyć.
RESULT_CODE_ERROR_NO_PROFILE_EMBEDDED- W uruchomionym pliku APK nie znaleziono profilu. Jeśli widzisz ten błąd, upewnij się, że używasz wersji kompilacji, która zawiera profile podstawowe, a plik APK zawiera profil.
RESULT_CODE_NO_PROFILE- Podczas instalowania aplikacji w sklepie z aplikacjami lub menedżerze pakietów nie zainstalowano profilu dla tej aplikacji. Główną przyczyną tego kodu błędu jest to, że instalator profilu nie został uruchomiony z powodu wyłączenia
ProfileInstallerInitializer. Pamiętaj, że gdy ten błąd jest zgłaszany, w pliku APK aplikacji nadal znajduje się profil osadzony. Jeśli nie znaleziono osadzonego profilu, zwracany jest kod błęduRESULT_CODE_ERROR_NO_PROFILE_EMBEDDED. RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION- Profil został znaleziony w pliku APK lub AAB i jest w kolejce do kompilacji. Gdy profil zostanie zainstalowany przez
ProfileInstaller, jest on umieszczany w kolejce do kompilacji przy następnym uruchomieniu przez system optymalizacji DEX w tle. Profil nie jest aktywny, dopóki kompilacja nie zostanie ukończona. Nie próbuj przeprowadzać testów porównawczych profili podstawowych, dopóki kompilacja się nie zakończy. Może być konieczne wymuszenie kompilacji profili podstawowych. Ten błąd nie wystąpi, gdy aplikacja zostanie zainstalowana ze Sklepu Play lub menedżera pakietów na urządzeniach z Androidem 9 (API 28) lub nowszym, ponieważ kompilacja jest przeprowadzana podczas instalacji. RESULT_CODE_COMPILED_WITH_PROFILE_NON_MATCHING- Zainstalowano niezgodny profil i aplikacja została z nim skompilowana.
Jest to wynik instalacji ze Sklepu Google Play lub menedżera pakietów.
Pamiętaj, że ten wynik różni się od
RESULT_CODE_COMPILED_WITH_PROFILE, ponieważ niepasujący profil będzie zawierać tylko metody, które są nadal udostępniane między profilem a aplikacją. Profil jest w praktyce mniejszy niż oczekiwano, a metod będzie mniej niż w profilu bazowym. RESULT_CODE_ERROR_CANT_WRITE_PROFILE_VERIFICATION_RESULT_CACHE_FILEProfileVerifiernie może zapisać pliku pamięci podręcznej z wynikami weryfikacji. Może to być spowodowane problemem z uprawnieniami do folderu aplikacji lub brakiem wolnego miejsca na dysku urządzenia.RESULT_CODE_ERROR_UNSUPPORTED_API_VERSION- ProfileVerifier
is running on an unsupported API version of Android. ProfileVerifierobsługuje tylko Androida 9 (poziom interfejsu API 28) i nowsze wersje. RESULT_CODE_ERROR_PACKAGE_NAME_DOES_NOT_EXIST- Wyjątek
PackageManager.NameNotFoundExceptionjest zgłaszany podczas wysyłania zapytania do elementuPackageManagero pakiet aplikacji. Rzadko się to zdarza. Spróbuj odinstalować aplikację i ponownie zainstalować wszystko. RESULT_CODE_ERROR_CACHE_FILE_EXISTS_BUT_CANNOT_BE_READ- Istnieje plik pamięci podręcznej z poprzednim wynikiem weryfikacji, ale nie można go odczytać. Rzadko się to zdarza. Spróbuj odinstalować aplikację i ponownie zainstalować wszystko.
Używanie ProfileVerifier w wersji produkcyjnej
W środowisku produkcyjnym możesz używać ProfileVerifier w połączeniu z bibliotekami raportowania analitycznego, takimi jak Google Analytics dla Firebase, aby generować zdarzenia analityczne wskazujące stan profilu. Na przykład ta funkcja szybko powiadamia, gdy zostanie wydana nowa wersja aplikacji, która nie zawiera profili podstawowych.
Wymuszanie kompilacji profili podstawowych
Jeśli stan kompilacji profili podstawowych to
RESULT_CODE_PROFILE_ENQUEUED_FOR_COMPILATION, możesz wymusić natychmiastową kompilację za pomocą tego polecenia: adb
adb shell cmd package compile -r bg-dexopt PACKAGE_NAME
Sprawdzanie stanu kompilacji profilu podstawowego bez ProfileVerifier
Jeśli nie używasz ProfileVerifier, możesz sprawdzić stan kompilacji za pomocą adb, ale nie daje on tak szczegółowych informacji jak ProfileVerifier:
adb shell dumpsys package dexopt | grep -A 2 PACKAGE_NAME
Użycie adb daje wynik podobny do tego:
[com.google.samples.apps.nowinandroid.demo]
path: /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/base.apk
arm64: [status=speed-profile] [reason=bg-dexopt] [primary-abi]
[location is /data/app/~~dzJiGMKvp22vi2SsvfjkrQ==/com.google.samples.apps.nowinandroid.demo-7FR1sdJ8ZTy7eCLwAnn0Vg==/oat/arm64/base.odex]
Wartość stanu wskazuje stan kompilacji profilu i jest jedną z tych wartości:
| Stan kompilacji | Znaczenie |
|---|---|
speed‑profile |
Istnieje skompilowany profil, który jest używany. |
verify |
Nie ma skompilowanego profilu. |
Stan verify nie oznacza, że plik APK lub AAB nie zawiera profilu, ponieważ może być w kolejce do skompilowania przez następne zadanie optymalizacji DEX w tle.
Wartość reason wskazuje, co wywołuje kompilację profilu, i jest jedną z tych wartości:
| Przyczyna | Znaczenie |
|---|---|
install‑dm
|
Profil podstawowy został skompilowany ręcznie lub przez Google Play podczas instalacji aplikacji. |
bg‑dexopt
|
Profil został utworzony, gdy urządzenie było nieaktywne. Może to być profil podstawowy lub profil zebrany podczas korzystania z aplikacji. |
cmdline
|
Kompilacja została wywołana za pomocą narzędzia adb. Może to być profil podstawowy lub profil zebrany podczas korzystania z aplikacji. |
Weryfikacja zgłoszenia profilu startupu do DEX i r8.json
Reguły profilu uruchamiania są używane podczas kompilacji przez R8 do optymalizacji układu klas w plikach DEX. Ta optymalizacja w czasie kompilacji różni się od sposobu używania profili podstawowych (baseline.prof), ponieważ są one pakowane w APK lub AAB, aby ART mógł przeprowadzać kompilację na urządzeniu. Reguły profilu uruchamiania są stosowane podczas samego procesu kompilacji, więc w pliku APK lub AAB nie ma oddzielnego pliku startup.prof, który można by sprawdzić. Efekt profili uruchamiania jest widoczny w układzie pliku DEX.
Sprawdzanie układu DEX za pomocą r8.json (zalecane w przypadku AGP 8.8 lub nowszego)
W przypadku projektów korzystających z wtyczki Androida do obsługi Gradle (AGP) w wersji 8.8 lub nowszej możesz sprawdzić, czy profil uruchamiania został zastosowany, sprawdzając wygenerowany plik r8.json. Ten plik jest spakowany w pakiecie AAB.
- Otwórz archiwum AAB i znajdź plik
r8.json. - Wyszukaj w pliku tablicę
dexFiles, która zawiera listę wygenerowanych plików DEX. Poszukaj
dexFilesobiektu zawierającego parę klucz-wartość"startup": true. Wyraźnie wskazuje to, że reguły profilu uruchamiania zostały zastosowane w celu zoptymalizowania układu tego konkretnego pliku DEX."dexFiles": [ { "checksum": "...", "startup": true // This flag confirms profile application to this DEX file }, // ... other DEX files ]
Sprawdzanie rozmieszczenia plików DEX we wszystkich wersjach wtyczki Androida do obsługi Gradle
Jeśli używasz AGP w wersji niższej niż 8.8, sprawdzanie plików DEX jest głównym sposobem weryfikacji, czy profil uruchamiania został prawidłowo zastosowany. Możesz też użyć tej metody, jeśli korzystasz z wtyczki Androida do obsługi Gradle w wersji 8.8 lub nowszej i chcesz ręcznie sprawdzić układ DEX. Na przykład jeśli nie widzisz oczekiwanej poprawy skuteczności. Aby sprawdzić umowę DEX, wykonaj te czynności:
- Otwórz plik AAB lub APK w Android Studio, klikając Build > Analyze APK (Utwórz > Przeanalizuj APK).
- Przejdź do pierwszego pliku DEX. Na przykład:
classes.dex. - Sprawdź zawartość tego pliku DEX. Powinno być możliwe sprawdzenie, czy krytyczne klasy i metody zdefiniowane w pliku profilu uruchamiania (
startup-prof.txt) znajdują się w tym głównym pliku DEX. Prawidłowe zastosowanie tej techniki oznacza, że kluczowe dla uruchomienia komponenty są ładowane w pierwszej kolejności.
problemy z wydajnością,
W tej sekcji znajdziesz sprawdzone metody prawidłowego definiowania i porównywania profili podstawowych, które pozwolą Ci w pełni wykorzystać ich potencjał.
Prawidłowe porównywanie danych dotyczących uruchamiania
Profile podstawowe będą skuteczniejsze, jeśli dane dotyczące uruchamiania aplikacji będą dobrze zdefiniowane. Dwa kluczowe rodzaje danych to czas do początkowego wyświetlenia (TTID) i czas do pełnego wyświetlenia (TTFD).
TTID to moment, w którym aplikacja rysuje pierwszą klatkę. Ważne jest, aby ten czas był jak najkrótszy, ponieważ wyświetlanie czegokolwiek pokazuje użytkownikowi, że aplikacja działa. Możesz nawet wyświetlić wskaźnik postępu o nieokreślonym stanie, aby pokazać, że aplikacja odpowiada na działania użytkownika.
TTFD to moment, w którym można wejść w interakcję z aplikacją. Warto zadbać o to, aby był jak najkrótszy, dzięki czemu użytkownicy nie będą się frustrować. Jeśli prawidłowo sygnalizujesz TTFD, informujesz system, że kod uruchamiany w drodze do TTFD jest częścią uruchamiania aplikacji. Dzięki temu system z większym prawdopodobieństwem umieści ten kod w profilu.
Utrzymuj jak najniższe wartości TTID i TTFD, aby aplikacja działała płynnie.
System może wykrywać TTID, wyświetlać go w Logcat i raportować w ramach testów porównawczych uruchamiania. System nie jest jednak w stanie określić czasu TTFD, dlatego to aplikacja musi zgłaszać, kiedy osiągnie w pełni wyrenderowany stan interaktywny. Możesz to zrobić, wywołując funkcję reportFullyDrawn() lub ReportDrawn, jeśli używasz Jetpack Compose. Jeśli masz kilka zadań w tle, które muszą zostać wykonane, zanim aplikacja zostanie w pełni narysowana, możesz użyć FullyDrawnReporter, jak opisano w artykule Poprawianie dokładności pomiaru czasu uruchamiania.
Profile biblioteki i profile niestandardowe
Podczas porównywania wpływu profili trudno jest oddzielić korzyści wynikające z profili aplikacji od profili dostarczonych przez biblioteki, takie jak biblioteki Jetpack. Podczas kompilacji pliku APK wtyczka Androida do obsługi Gradle dodaje wszystkie profile w zależnościach bibliotek, a także Twój profil niestandardowy. Jest to przydatne do optymalizacji ogólnej wydajności i zalecane w przypadku wersji produkcyjnych. Utrudnia to jednak pomiar dodatkowego wzrostu wydajności wynikającego z używania profilu niestandardowego.
Szybkim sposobem na ręczne sprawdzenie dodatkowej optymalizacji zapewnianej przez profil niestandardowy jest jego usunięcie i przeprowadzenie testów porównawczych. Następnie wymień go i ponownie uruchom testy porównawcze. Porównanie tych dwóch wartości pokaże optymalizacje zapewniane przez same profile biblioteki oraz przez profile biblioteki w połączeniu z Twoim profilem niestandardowym.
Automatyczny sposób porównywania profili polega na utworzeniu nowego wariantu kompilacji, który zawiera tylko profile biblioteki, a nie profil niestandardowy. Porównaj
wartości referencyjne tego wariantu z wariantem wersji, który zawiera zarówno profile
biblioteki, jak i profile niestandardowe. Poniższy przykład pokazuje, jak skonfigurować wariant, który zawiera tylko profile bibliotek. Dodaj do modułu konsumenta profilu nowy wariant o nazwie releaseWithoutCustomProfile, który zwykle jest modułem aplikacji:
Kotlin
android { ... buildTypes { ... // Release build with only library profiles. create("releaseWithoutCustomProfile") { initWith(release) } ... } ... } ... dependencies { ... // Remove the baselineProfile dependency. // baselineProfile(project(":baselineprofile")) } baselineProfile { variants { create("release") { from(project(":baselineprofile")) } } }
Groovy
android { ... buildTypes { ... // Release build with only library profiles. releaseWithoutCustomProfile { initWith(release) } ... } ... } ... dependencies { ... // Remove the baselineProfile dependency. // baselineProfile ':baselineprofile"' } baselineProfile { variants { release { from(project(":baselineprofile")) } } }
W przykładzie kodu powyżej usunięto zależność baselineProfile ze wszystkich wariantów i zastosowano ją tylko do wariantu release. Może się wydawać sprzeczne z intuicją, że profile biblioteki są nadal dodawane, gdy usunięto zależność od modułu producenta profilu. Ten moduł odpowiada jednak tylko za generowanie niestandardowego profilu. Wtyczka Androida do obsługi Gradle nadal działa w przypadku wszystkich wariantów i jest odpowiedzialna za uwzględnianie profili bibliotek.
Musisz też dodać nowy wariant do modułu generatora profili. W tym przykładzie moduł producenta ma nazwę :baselineprofile.
Kotlin
android { ... buildTypes { ... // Release build with only library profiles. create("releaseWithoutCustomProfile") {} ... } ... }
Groovy
android { ... buildTypes { ... // Release build with only library profiles. releaseWithoutCustomProfile {} ... } ... }
Gdy uruchamiasz test porównawczy w Android Studio, wybierz wariant releaseWithoutCustomProfile, aby zmierzyć wydajność tylko za pomocą profili biblioteki, lub wariant release, aby zmierzyć wydajność za pomocą profili biblioteki i profili niestandardowych.
Unikaj uruchamiania aplikacji zależnego od operacji wejścia/wyjścia
Jeśli aplikacja wykonuje wiele wywołań wejścia/wyjścia lub wywołań sieciowych podczas uruchamiania, może to negatywnie wpłynąć zarówno na czas uruchamiania aplikacji, jak i na dokładność testów porównawczych uruchamiania. Te wymagające wywołania mogą trwać nieokreślony czas, który może się zmieniać z czasem, a nawet między iteracjami tego samego testu porównawczego. Wywołania wejścia/wyjścia są zwykle lepsze niż wywołania sieciowe, ponieważ na te ostatnie mogą wpływać czynniki zewnętrzne i wewnętrzne. Unikaj połączeń sieciowych podczas uruchamiania. Jeśli użycie jednego z tych terminów jest nieuniknione, użyj terminu „wejście/wyjście”.
Zalecamy, aby architektura aplikacji obsługiwała uruchamianie aplikacji bez wywołań sieciowych ani wywołań wejścia/wyjścia, nawet jeśli ma to służyć tylko do testowania uruchamiania. Pozwala to zapewnić jak najmniejszą zmienność między różnymi iteracjami wartości porównawczych.
Jeśli Twoja aplikacja korzysta z Hilt, możesz podczas testów porównawczych w Microbenchmark i Hilt udostępniać fałszywe implementacje związane z wejściem/wyjściem.
Obejmuj wszystkie ważne ścieżki użytkowników
Ważne jest, aby w procesie generowania profilu podstawowego uwzględnić wszystkie ważne ścieżki użytkowników. Ścieżki użytkowników, które nie są objęte tymi profilami, nie zostaną przez nie ulepszone. Najskuteczniejsze profile podstawowe obejmują wszystkie typowe ścieżki użytkowników podczas uruchamiania aplikacji, a także ścieżki użytkowników w aplikacji, które są wrażliwe na wydajność, np. przewijanie list.
Testy A/B zmian profilu w czasie kompilacji
Profile uruchomieniowe i podstawowe są optymalizacją czasu kompilacji, więc bezpośrednie testowanie A/B różnych plików APK w Sklepie Google Play nie jest zwykle obsługiwane w przypadku wersji produkcyjnych. Aby ocenić wpływ w środowisku podobnym do produkcyjnego, rozważ te podejścia:
Wersja poza cyklem: prześlij wersję poza cyklem do niewielkiego odsetka użytkowników, która zawiera tylko zmianę profilu. Pozwala to zbierać rzeczywiste dane o różnicach w skuteczności.
Lokalne testy porównawcze: lokalnie porównuj wydajność aplikacji z zastosowanym profilem i bez niego. Pamiętaj jednak, że lokalne testy porównawcze pokazują najlepszy scenariusz dla profili, ponieważ nie uwzględniają efektów profili w chmurze z ART, które są obecne na urządzeniach produkcyjnych.