Per scoprire come utilizzare la libreria Microbenchmark aggiungendo modifiche al codice dell'applicazione, consulta la sezione Guida rapida. Per scoprire come completare una configurazione completa con modifiche più complesse alla base di codice, 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 risultati accurati sul rendimento, questi passaggi richiedono la disattivazione del debug nell'app, quindi mantieni questa operazione in una copia di lavoro locale senza eseguire il commit delle modifiche nel sistema di controllo delle versioni.
Per eseguire un benchmarking una tantum:
Aggiungi la raccolta al file
build.gradle
obuild.gradle.kts
del modulo:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Groovy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Utilizza una dipendenza
implementation
anziché una dipendenzaandroidTestImplementation
. Se utilizziandroidTestImplementation
, i benchmark non vengono eseguiti perché il manifest della libreria non viene unito al manifest dell'app.Aggiorna il tipo di build
debug
in modo che non sia possibile eseguire il debug:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Modifica
testInstrumentationRunner
inAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Groovy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Aggiungi un'istanza di
BenchmarkRule
in un file di test nella directoryandroidTest
per aggiungere il benchmark. Per ulteriori informazioni sulla scrittura di benchmark, consulta Creare una classe di microbenchmark.Il seguente snippet di codice mostra come aggiungere un benchmark a un test instrumentato:
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 un benchmark.
Configurazione completa del progetto
Per configurare un benchmarking regolare anziché una singola misurazione, isola i benchmark in un proprio modulo. In questo modo, la loro configurazione, come l'impostazione di debuggable
su false
, è separata dai test regolari.
Poiché Microbenchmark esegue direttamente il codice, inserisci il codice di cui vuoi eseguire il benchmark in un modulo Gradle separato e imposta la dipendenza da quel modulo come mostrato nella figura 1.
Per aggiungere un nuovo modulo Gradle, puoi utilizzare la procedura guidata del modulo 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 tasto destro del mouse sul progetto o sul modulo nel riquadro Project (Progetto) di Android Studio e poi su New > Module (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 file build.gradle
o build.gradle.kts
e aggiungi androidTestImplementation
al modulo contenente il codice da eseguire in benchmark:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
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 eseguire il benchmarking delle attività, utilizza
ActivityScenario
o ActivityScenarioRule
. Per eseguire il benchmark del codice dell'interfaccia utente,
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(); } } }
Disattivare la temporizzazione per la configurazione
Puoi disattivare il rilevamento dei tempi per le sezioni di codice che non vuoi misurare con il blocco
runWithTimingDisabled{}
. Queste sezioni in genere rappresentano del codice da eseguire in 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 il 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 affermare l'ultimo risultato
invece di farlo ogni iterazione del benchmark.
Esegui il benchmark
In Android Studio, esegui il benchmark come faresti con qualsiasi @Test
utilizzando l'azione del riquadro accanto al metodo o alla classe 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 un singolo test:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Risultati del benchmark
Dopo un'esecuzione corretta del microbenchmark, le metriche vengono visualizzate direttamente in Android Studio e un report completo del benchmark con metriche aggiuntive 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. Questi vengono scritti sulla macchina 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 sul disco del dispositivo nella
cartella dei contenuti multimediali condivisi esterni dell'APK di test, che in genere si trova in
/storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Errori di configurazione
La libreria rileva le seguenti condizioni per assicurarsi che il progetto e l'ambiente siano configurati per prestazioni accurate in base alla release:
- La modalità di debug è impostata su
false
. - Viene utilizzato un dispositivo fisico: gli emulatori non sono supportati.
- Gli orologi sono bloccati se il dispositivo è rooted.
- Livello batteria sufficiente sul dispositivo di almeno il 25%.
Se uno dei controlli precedenti non va a buon fine, il benchmark genera un errore per dissuadere dall'uso di misurazioni imprecise.
Per eliminare tipi di errori specifici come avvisi ed evitare che interrompano il benchmark, passa il tipo di errore in un elenco separato da virgole all'argomento di misurazione androidx.benchmark.suppressErrors
.
Puoi impostarlo dallo script Gradle, come mostrato nell'esempio seguente:
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Groovy
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 l'esecuzione del benchmark in uno stato configurato in modo errato e l'output del benchmark viene rinominato intenzionalmente anteponendo ai nomi dei test l'errore. Ad esempio, l'esecuzione di un benchmark di cui è possibile eseguire il debug con la soppressione nello snippet precedente antepone ai nomi dei test DEBUGGABLE_
.
Consigliati per te
- Nota: il testo del link viene visualizzato quando JavaScript è disattivato
- Scrivere un benchmark macro
- Creare microbenchmark senza Gradle
- Creare profili di baseline {:#creating-profile-rules}