Consulta la sezione Guida rapida per scoprire come utilizzare la libreria Microbenchmark aggiungendo modifiche al codice dell'applicazione. Per scoprire come completare una configurazione completa con modifiche più complicate al codebase, consulta la sezione Configurazione completa del progetto.
Guida rapida
Questa sezione mostra come provare il benchmarking ed eseguire misurazioni una tantum senza dover spostare il codice nei moduli. Per ottenere risultati precisi in termini di prestazioni, questi passaggi prevedono la disattivazione del debug nell'app, quindi conserva una copia di lavoro locale senza eseguire il commit delle modifiche nel sistema di controllo del codice sorgente.
Per eseguire il benchmarking una tantum:
Aggiungi la libreria al file
build.gradle
obuild.gradle.kts
del tuo modulo:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.3") }
trendy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.3' }
Utilizza una dipendenza
implementation
anziché una dipendenzaandroidTestImplementation
. Se utilizziandroidTestImplementation
, i benchmark non vengono eseguiti perché il file manifest della libreria non viene unito al file manifest dell'app.Aggiorna il tipo di build
debug
in modo che non sia possibile eseguire il debug:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
trendy
android { ... buildTypes { debug { debuggable false } } }
Cambia
testInstrumentationRunner
inAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
trendy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Aggiungi un'istanza di
BenchmarkRule
in un file di test nella directoryandroidTest
per aggiungere il tuo benchmark. Per ulteriori informazioni sulla scrittura di benchmark, consulta Creare una classe Microbenchmark.Il seguente snippet di codice mostra come aggiungere un benchmark a un test strumentale:
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() ); } } }
Per scoprire come scrivere un benchmark, vai a Creare una classe di Microbenchmark.
Configurazione completa del progetto
Per impostare un benchmarking regolare anziché benchmarking una tantum, isola i benchmark in un modulo dedicato. Ciò contribuisce a garantire che la configurazione, ad esempio l'impostazione di debuggable
su false
, sia separata dai normali test.
Poiché Microbenchmark esegue il codice direttamente, inserisci il codice che vuoi eseguire il benchmarking in un modulo Gradle separato e imposta la dipendenza su quel modulo come mostrato nella Figura 1.
Per aggiungere un nuovo modulo Gradle, puoi utilizzare la procedura guidata per i moduli in Android Studio. La procedura guidata crea un modulo preconfigurato per il benchmarking, con una directory di benchmark aggiunta e debuggable
impostato su false
.
Fai clic con il pulsante destro del mouse sul progetto o modulo nel riquadro Progetto in Android Studio e fai clic su Nuovo > Modulo.
Seleziona Benchmark nel riquadro Modelli.
Seleziona Microbenchmark come tipo di modulo di benchmark.
Digita "microbenchmark" come nome del modulo.
Fai clic su Fine.
Dopo aver creato il modulo, modifica il relativo file build.gradle
o build.gradle.kts
e aggiungi androidTestImplementation
al modulo contenente il codice come
benchmark:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
trendy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Crea una classe Microbenchmark
I benchmark sono test di strumentazione standard. Per creare un benchmark, utilizza la classe BenchmarkRule
fornita dalla libreria. Per confrontare le attività, utilizza
ActivityScenario
o ActivityScenarioRule
. Per confrontare il codice UI,
utilizza @UiThreadTest
.
Il seguente codice mostra un benchmark di esempio:
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(); } } }
Disattiva la tempistica per la configurazione
Puoi disattivare la sincronizzazione per le sezioni di codice che non vuoi misurare con il blocco runWithTimingDisabled{}
. Queste sezioni di solito rappresentano
parte del codice che devi eseguire a ogni iterazione del benchmark.
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)); }
Cerca di ridurre al minimo la quantità di lavoro svolto all'interno del blocco measureRepeated
e all'interno di runWithTimingDisabled
. Il blocco measureRepeated
viene eseguito più
volte e può influire sul tempo complessivo necessario per eseguire il benchmark. Se devi verificare alcuni risultati di un benchmark, puoi dichiarare l'ultimo risultato invece di eseguire ogni iterazione del benchmark.
Esegui il benchmark
In Android Studio, esegui il benchmark come fai con qualsiasi @Test
utilizzando l'azione grotter accanto alla classe o al metodo di test, come mostrato nella Figura 3.
In alternativa, dalla riga di comando, esegui connectedCheck
per eseguire tutti
i test dal modulo Gradle specificato:
./gradlew benchmark:connectedCheck
Oppure per un singolo test:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Risultati benchmark
Dopo un'esecuzione riuscita di Microbenchmark, le metriche vengono visualizzate direttamente in Android Studio e un report di benchmark completo con ulteriori metriche e informazioni sul dispositivo è disponibile in formato JSON.
Anche i report JSON e le eventuali tracce di profilazione vengono copiati automaticamente dal dispositivo all'host. che sono scritte sul computer host nel seguente percorso:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Per impostazione predefinita, il report JSON viene scritto su disco on-device nella cartella esterna dei contenuti multimediali condivisi dell'APK di test, che si trova in genere in /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Errori di configurazione
La libreria rileva le seguenti condizioni per garantire che il progetto e l'ambiente siano configurati in modo da ottenere prestazioni accurate per la release:
- Il debug è impostato su
false
. - È in uso un dispositivo fisico. Gli emulatori non sono supportati.
- Gli orologi sono bloccati se il dispositivo è rooted.
- Livello della batteria del dispositivo sufficiente (almeno il 25%).
Se uno dei controlli precedenti non va a buon fine, il benchmark segnala un errore per scoraggiare le misurazioni imprecise.
Per eliminare tipi di errore specifici come avvisi e impedire che interrompano il benchmark, passa il tipo di errore all'argomento strumentazione androidx.benchmark.suppressErrors
in un elenco separato da virgole.
Puoi impostarlo dallo script Gradle, come mostrato nell'esempio seguente:
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
trendy
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Puoi anche eliminare gli errori dalla riga di comando:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
L'eliminazione degli errori consente di eseguire il benchmark in uno stato configurato in modo errato e l'output del benchmark viene rinominato intenzionalmente anteponendo l'errore ai nomi dei test. Ad esempio, l'esecuzione di un benchmark di cui è possibile eseguire il debug con l'eliminazione nello snippet precedente antepone i nomi dei test con DEBUGGABLE_
.
Consigliato per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Scrivi un Macrobenchmark
- Crea microbenchmark senza Gradle
- Crea profili di riferimento {:#Creating-profile-rules}