Puoi eseguire benchmark in integrazione continua (CI) per monitorare le prestazioni nel tempo e riconoscere regressioni o miglioramenti delle prestazioni prima ancora che l'app venga rilasciata. Questa pagina fornisce informazioni di base sul benchmarking in CI.
Prima di iniziare a utilizzare il benchmarking nella CI, valuta le differenze di acquisizione e valutazione dei risultati rispetto ai test normali.
Risultati parziali
Sebbene i benchmark siano test strumentati, i risultati non indicano semplicemente che il test è stato superato o meno. I benchmark forniscono misurazioni dei tempi per il dispositivo su cui vengono eseguiti. I grafici dei risultati nel tempo consentono di monitorare le variazioni e osservare il rumore nel sistema di misurazione.
Usa dispositivi reali
Eseguire benchmark su dispositivi Android fisici. Nonostante possano essere eseguiti su emulatori, sconsigliamo vivamente di utilizzarli perché non offrono un'esperienza utente realistica e forniscono numeri associati al sistema operativo host e alle funzionalità hardware. Potresti utilizzare dispositivi reali o un servizio che ti consenta di eseguire test su dispositivi reali, come Firebase Test Lab.
Esegui i benchmark
L'esecuzione dei benchmark all'interno della pipeline CI potrebbe essere diversa da quella locale da Android Studio. A livello locale, in genere esegui i test di integrazione Android con un'attività Gradle connectedCheck
. Questa attività crea automaticamente l'APK e l'APK di test, quindi esegue i test sui dispositivi connessi al server CI. Quando viene eseguito in CI, solitamente questo flusso deve essere suddiviso in
fasi separate.
Crea
Per la libreria Microbenchmark, esegui l'attività Gradle assemble[VariantName]AndroidTest
, che crea l'APK di test contenente sia il codice dell'applicazione sia il codice testato.
In alternativa, la libreria Macrobenchmark richiede di creare separatamente l'APK di destinazione e l'APK di test. Pertanto, esegui le attività :app:assemble[VariantName]
e
:macrobenchmark:assemble[VariantName]
Gradle.
Installa ed esegui
In genere, questi passaggi vengono eseguiti senza dover eseguire attività Gradle. Tieni presente che possono essere astratte a seconda che utilizzi o meno un servizio che ti consente di eseguire test su dispositivi reali.
Per l'installazione, utilizza il comando adb install
e specifica l'APK di test o l'APK di destinazione.
Esegui il comando adb shell am
instrument per eseguire tutti i benchmark:
adb shell am instrument -w com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Quando usi la libreria Macrobenchmark, usa normale
androidx.test.runner.AndroidJUnitRunner
come runner della strumentazione.
Puoi passare gli stessi argomenti di strumentazione della configurazione Gradle utilizzando l'argomento -e
. Per tutte le opzioni di argomenti di strumentazione, consulta
Argomenti di strumentazione Microbenchmark o
Aggiungere argomenti di strumentazione per Macrobenchmark.
Ad esempio, puoi impostare l'argomento dryRunMode
per eseguire microbenchmark nell'ambito del processo di verifica delle richieste di pull. Con questo flag abilitato, i microservizi vengono eseguiti in un solo loop, verificando che siano eseguiti correttamente senza richiedere troppo tempo.
adb shell am instrument -w -e "androidx.benchmark.dryRunMode.enable" "true" com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Per maggiori informazioni su come eseguire i test di strumentazione dalla riga di comando, vedi Eseguire test con ADB.
Blocca orologi
Il plug-in Gradle Microbenchmark fornisce il comando ./gradlew lockClocks
per bloccare i clock della CPU di un dispositivo rooted. Ciò è utile per garantire stabilità quando hai accesso a dispositivi rooted, come le build "userdebug". Puoi
replicare con lo script shell lockClocks.sh
, disponibile nell'
origine della libreria.
Puoi eseguire lo script direttamente da un host Linux o Mac oppure eseguire il push al dispositivo con alcuni comandi adb:
adb push path/lockClocks.sh /data/local/tmp/lockClocks.sh adb shell /data/local/tmp/lockClocks.sh adb shell rm /data/local/tmp/lockClocks.sh
Se esegui lo script shell direttamente su un host, questo invia i comandi a un dispositivo connesso.
Per ulteriori informazioni sul motivo per cui è utile bloccare i clock della CPU, scopri come ottenere benchmark coerenti.
Raccogli i risultati
Le librerie di benchmarking forniscono le misurazioni in JSON, insieme alle tracce di profilazione su una directory sul dispositivo Android dopo ogni esecuzione di benchmark. La libreria Macrobenchmark genera più file di traccia perfetti: uno per iterazione misurata di ogni loop MacrobenchmarkRule.measureRepeated
. Microbenchmark, tuttavia, crea
un solo file di traccia per tutte le iterazioni di
BenchmarkRule.measureRepeated
. Anche i file di traccia di profilazione vengono inviati a questa stessa directory.
Salva e individua i file
Se esegui i benchmark con Gradle, questi file vengono copiati automaticamente nella directory di output del computer host in build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/
.
Se l'esecuzione avviene direttamente con il comando adb
, devi estrarre i file manualmente. Per impostazione predefinita, i report vengono salvati sul dispositivo nella directory dei contenuti multimediali della memoria esterna dell'app testata. Per praticità, la libreria stampa il percorso
del file in Logcat. Tieni presente che la cartella di output può essere diversa a seconda della versione di Android su cui sono in esecuzione i benchmark.
Benchmark: writing results to /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Puoi anche configurare la località in cui vengono salvati i report di benchmark sul
dispositivo utilizzando l'argomento strumentazione additionalTestOutputDir
. La tua app deve poter scrivere questa cartella.
adb shell am instrument -w -e additionalTestOutputDir /sdcard/Download/ com.example.benchmark/androidx.benchmark.junit4.AndroidBenchmarkRunner
Su Android 10 (livello API 29) e versioni successive, per impostazione predefinita i test dell'app vengono eseguiti in una sandbox di archiviazione, il che impedisce all'app di accedere ai file al di fuori della directory specifica dell'app. Per poter eseguire il salvataggio in una directory globale, ad esempio /sdcard/Download
, passa il seguente argomento di strumentazione:
-e no-isolated-storage true
Devi inoltre consentire esplicitamente le opzioni di archiviazione legacy nel file manifest del benchmark:
<application android:requestLegacyExternalStorage="true" ... >
Per ulteriori informazioni, consulta Disattivare temporaneamente l'archiviazione con ambito.
Recupera i file
Per recuperare i file generati dal dispositivo, utilizza il comando adb pull
, che esegue il pull del file specificato nella directory corrente sul tuo host:
adb pull /storage/emulated/0/Android/media/com.example.macrobenchmark/com.example.macrobenchmark-benchmarkData.json
Per recuperare tutti i benchmarkData
da una cartella specificata, controlla il seguente snippet:
# The following command pulls all files ending in -benchmarkData.json from the directory
# hierarchy starting at the root /storage/emulated/0/Android.
adb shell find /sdcard/Download -name "*-benchmarkData.json" | tr -d '\r' | xargs -n1 adb pull
I file di traccia (.trace
o .perfetto-trace
) vengono salvati nella stessa cartella del file benchmarkData.json
e puoi raccoglierli nello stesso modo.
Esempio di dati di benchmark
Le librerie di benchmark generano file JSON contenenti informazioni sul dispositivo su cui stavano eseguendo i benchmark e sui benchmark effettivi eseguiti. Il seguente snippet rappresenta il file JSON generato:
{
"context": {
"build": {
"brand": "google",
"device": "blueline",
"fingerprint": "google/blueline/blueline:12/SP1A.210812.015/7679548:user/release-keys",
"model": "Pixel 3",
"version": {
"sdk": 31
}
},
"cpuCoreCount": 8,
"cpuLocked": false,
"cpuMaxFreqHz": 2803200000,
"memTotalBytes": 3753299968,
"sustainedPerformanceModeEnabled": false
},
"benchmarks": [
{
"name": "startup",
"params": {},
"className": "com.example.macrobenchmark.startup.SampleStartupBenchmark",
"totalRunTimeNs": 4975598256,
"metrics": {
"timeToInitialDisplayMs": {
"minimum": 347.881076,
"maximum": 347.881076,
"median": 347.881076,
"runs": [
347.881076
]
}
},
"sampledMetrics": {},
"warmupIterations": 0,
"repeatIterations": 3,
"thermalThrottleSleepSeconds": 0
}
]
}
Risorse aggiuntive
- Per indicazioni su come rilevare le regressioni delle prestazioni, consulta Contrastare le regressioni con i benchmark in CI.
- Per scoprire come configurare le azioni di GitHub con Firebase Test Lab, consulta la pagina Configurazione di Macrobenchmarks Jetpack per CI
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Best practice per le prestazioni di SQLite
- Creare e misurare profili di riferimento senza Macrobenchmark
- Wakelock parziali bloccati