Para aprender a usar la biblioteca de Microbenchmark con la incorporación de cambios a tu código de la aplicación, consulta la sección Guía de inicio rápido. Si quieres aprender a completar una configuración entera con cambios más complejos en la base de código, consulta la sección Configuración completa del proyecto.
Guía de inicio rápido
En esta sección, se muestra cómo probar las comparativas y ejecutar mediciones únicas sin necesidad de mover código a los módulos. Para obtener resultados de rendimiento precisos, estos pasos implican inhabilitar la depuración en tu app, por lo que debes conservar esta configuración en una copia de trabajo local sin confirmar los cambios en el sistema fuente de control.
Para generar rápidamente comparativas únicas, completa los siguientes pasos:
Agrega la biblioteca al archivo
build.gradle
obuild.gradle.kts
de tu módulo:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.4") }
Groovy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.4' }
Usa una dependencia
implementation
en lugar de una dependenciaandroidTestImplementation
. Si usasandroidTestImplementation
, las comparativas no se ejecutan porque el manifiesto de la biblioteca no se combina con el manifiesto de la app.Actualiza el tipo de compilación
debug
para que no se pueda depurar:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Cambia
testInstrumentationRunner
aAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Groovy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Agrega una instancia de
BenchmarkRule
a un archivo de prueba del directorioandroidTest
para agregar tus comparativas. Consulta Cómo crear una clase de Microbenchmark para descubrir cómo escribir comparativas.En el siguiente fragmento de código, se muestra cómo agregar comparativas a una prueba de instrumentación:
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() ); } } }
Si deseas aprender a escribir comparativas, avanza a Cómo crear una clase de Microbenchmark.
Configuración completa del proyecto
Para configurar la generación de comparativas regulares en lugar de las comparativas únicas, debes aislarlas en su propio módulo. Esto ayuda a garantizar que su configuración, como establecer debuggable
en false
, sea independiente de las pruebas regulares.
Debido a que Microbenchmark ejecuta tu código directamente, coloca el código que deseas comparar en un módulo de Gradle separado y establece la dependencia en ese módulo, como se muestra en la figura 1.
Para agregar un nuevo módulo de Gradle, puedes usar el asistente de módulos en Android Studio. El asistente crea un módulo configurado previamente para la generación de comparativas, con un directorio de comparativas y el valor debuggable
configurado como false
.
Haz clic con el botón derecho en tu proyecto o módulo desde el panel Project en Android Studio y, luego, haz clic en New > Module.
Selecciona Benchmark en el panel Templates.
Selecciona Microbenchmark como tipo de módulo de comparativas.
Como nombre de módulo, escribe "microbenchmark".
Haz clic en Finish.
Después de crear el módulo, cambia su archivo build.gradle
o build.gradle.kts
, y agrega androidTestImplementation
al módulo que contiene el código para crear comparativas:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Cómo crear una clase de Microbenchmark
Las comparativas son pruebas de instrumentación estándar. Para crear comparativas, usa la clase BenchmarkRule
que proporciona la biblioteca. Si deseas comparar actividades, usa ActivityScenario
o ActivityScenarioRule
. Usa @UiThreadTest
para comparar código de IU.
En el siguiente código se muestran comparativas de ejemplo:
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(); } } }
Cómo inhabilitar la sincronización
Puedes inhabilitar la sincronización de las secciones de código que no quieres medir con el bloque runWithTimingDisabled{}
. Por lo general, estas secciones representan algún código que necesitas ejecutar en cada iteración de la comparativa.
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)); }
Intenta minimizar la cantidad de trabajo realizado dentro del bloque measureRepeated
y dentro de runWithTimingDisabled
. El bloque measureRepeated
se ejecuta varias veces y puede afectar el tiempo general necesario para ejecutar la comparativa. Si necesitas verificar algunos resultados de una comparativa, puedes confirmar el último resultado en lugar de hacerlo en cada iteración de la comparativa.
Cómo ejecutar las comparativas
En Android Studio, ejecuta tus comparativas como lo haces con cualquier @Test
usando la acción del margen junto a tu clase o método de prueba, como se muestra en la figura 3.
Como alternativa, desde la línea de comandos, ejecuta connectedCheck
para ejecutar todas las pruebas del módulo de Gradle especificado:
./gradlew benchmark:connectedCheck
También puedes ejecutar una sola prueba:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Resultados de comparativas
Después de ejecutar Microbenchmark con éxito, se muestran las métricas directamente en Android Studio, así como un informe de comparativas completo con información adicional del dispositivo y métricas disponibles en formato JSON.
Los informes de JSON y cualquier registro de generación de perfiles también se copian automáticamente del dispositivo al host. Están escritos en la máquina anfitrión en la siguiente ubicación:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
De forma predeterminada, el informe de JSON se escribe en el disco del dispositivo, en la carpeta externa del APK de prueba de contenido multimedia compartido que, por lo general, se encuentra en /storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Errores de configuración
La biblioteca detecta las siguientes condiciones a fin de garantizar que tu proyecto y entorno estén configurados para un rendimiento acorde a un lanzamiento:
- Debuggable está configurado en
false
. - Se está usando un dispositivo físico; no se admiten emuladores.
- Los relojes están bloqueados si el dispositivo tiene permisos de administrador.
- El nivel de batería en el dispositivo es suficiente (es de al menos 25%).
Si falla alguna de las verificaciones anteriores, las comparativas informan un error para evitar mediciones imprecisas.
Para hacer que algunos tipos de error específicos pasen como advertencias y evitar que detengan las comparativas, pasa el tipo de error en una lista separada por comas al argumento de instrumentación androidx.benchmark.suppressErrors
.
Puedes configurar esto desde tu secuencia de comandos de Gradle, como se muestra en el siguiente ejemplo:
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Groovy
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
También puedes suprimir errores desde la línea de comandos:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
Ten en cuenta que suprimir errores permite que las comparativas se ejecuten en un estado de configuración incorrecta, pero se le cambiará intencionalmente el nombre del resultado de las comparativas anteponiendo nombres de pruebas con el error. Por ejemplo, ejecutar una comparativa depurable con la supresión del fragmento anterior antepone DEBUGGABLE_
a los nombres de prueba.
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Cómo escribir una macrocomparativa
- Cómo compilar microcomparativas sin Gradle
- Cómo crear perfiles de Baseline {:#creating-profile-rules}