Usa la biblioteca de Macrobenchmark para probar los casos de uso más grandes de tu app, incluido su inicio y las manipulaciones de IU complejas, como desplazarse por una RecyclerView
o ejecutar animaciones. Si quieres probar áreas más pequeñas de tu código, consulta la biblioteca de Microbenchmark. En esta página, se muestra cómo configurar la biblioteca de Macrobenchmark.
La biblioteca genera resultados de comparativas tanto en la consola de Android Studio como en un archivo JSON con más detalles. También proporciona archivos de registro que puedes cargar y analizar en Android Studio.
Usa la biblioteca de Macrobenchmark en un entorno de integración continua (CI), como se describe en Cómo obtener comparativas en integración continua.
Puedes usar Macrobenchmark para generar perfiles de Baseline. Primero, configura la biblioteca de Macrobenchmark y, luego, podrás crear un perfil de Baseline.
Configuración del proyecto
Te recomendamos que uses Macrobenchmark con la versión más reciente de Android Studio para las funciones del IDE que se integran con Macrobenchmark.
Configura el módulo de Macrobenchmark
Las macrocomparativas requieren un módulo com.android.test
independiente del código de tu app en el que se ejecuten las pruebas que miden la app.
En Android Studio, hay una plantilla disponible para simplificar la configuración del módulo de Macrobenchmark. Esta plantilla crea automáticamente un módulo en el proyecto para medir la app que compila un módulo de app, incluida una comparativa de inicio de muestra.
Si deseas usar la plantilla del módulo para crear un módulo nuevo, haz lo siguiente:
Haz clic con el botón derecho en tu proyecto o módulo desde el panel Project en Android Studio, y luego selecciona New > Module.
Selecciona Benchmark en el panel Templates. Puedes personalizar la aplicación de destino (la app de la que obtendrás comparativas), así como el nombre del paquete y del módulo para el módulo nuevo de Macrobenchmark.
Haz clic en Finish.
Cómo configurar la app
Para obtener comparativas de una app, lo que se conoce como el objetivo de Macrobenchmark, esta debe ser profileable
, lo que permite leer información de seguimiento detallada sin afectar el rendimiento. El asistente de módulos agrega la etiqueta <profileable>
automáticamente al archivo AndroidManifest.xml
de la app.
Asegúrate de que la app de destino incluya
ProfilerInstaller
1.3 o
superior, que la biblioteca de Macrobenchmark necesita para habilitar la captura de perfiles y
el restablecimiento y el borrado
de la caché del sombreador.
Configura la app de la que obtendrás comparativas de la forma más parecida posible a la versión de actualización (o producción). Además, configúrala como no depurable y con la reducción activada en lo posible, lo que mejorará el rendimiento. Para ello, en general, debes crear una copia de la variante de la versión, que tendrá el mismo rendimiento, pero se firma de manera local con claves de depuración.
Como alternativa, puedes usar initWith
para indicar a Gradle que lo haga por ti:
Kotlin
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") } }
Groovy
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" ) // In real app, this would use its own release keystore signingConfig = signingConfigs.getByName("debug") } }
Para asegurarte de que la ejecución de las comparativas compile y pruebe la variante correcta de tu app, como se muestra en la Figura 2, haz lo siguiente:
- Realiza una sincronización de Gradle.
- Abre el panel Build Variants.
- Selecciona la variante de comparativas de la app y del módulo de Macrobenchmark.
Cómo configurar una app con varios módulos (opcional)
Si tu app tiene más de un módulo de Gradle, asegúrate de que las secuencias de comandos de compilación sepan qué variante de compilación compilar. Agrega la propiedad matchingFallbacks
al tipo de compilación benchmark
de tus módulos :macrobenchmark
y :app
. El resto de los módulos de Gradle puede tener la misma configuración que antes.
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") }
Groovy
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
De lo contrario, el tipo de compilación benchmark
que se agregó recientemente hace que la compilación falle y muestra el siguiente mensaje de error:
> Could not resolve project :shared.
Required by:
project :app
> No matching variant of project :shared was found.
...
Cuando selecciones las variantes de compilación de tu proyecto, elige benchmark
para los módulos :app
y :macrobenchmark
, y release
para cualquier otro módulo que tengas en tu app, como se muestra en la Figura 3:
Para obtener más información, consulta Cómo usar la administración de dependencias con reconocimiento de variantes.
Cómo configurar las variantes de producto (opcional)
Si configuraste más de una variante de producto en la app, configura el módulo :macrobenchmark
para que sepa qué tipo de variante compilar y comparar.
En los ejemplos de esta página, se usan las dos variantes de producto del módulo :app
, demo
y production
, como se muestra en el siguiente fragmento:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
Sin esta configuración, es posible que recibas un error de compilación similar al de varios módulos de Gradle:
Could not determine the dependencies of task ':macrobenchmark:connectedBenchmarkAndroidTest'.
> Could not determine the dependencies of null.
> Could not resolve all task dependencies for configuration ':macrobenchmark:benchmarkTestedApks'.
> Could not resolve project :app.
Required by:
project :macrobenchmark
> The consumer was configured to find a runtime of a component, as well as attribute 'com.android.build.api.attributes.BuildTypeAttr' with value 'benchmark', attribute 'com.android.build.api.attributes.AgpVersionAttr' with value '7.3.0'. However we cannot choose between the following variants of project :app:
- demoBenchmarkRuntimeElements
- productionBenchmarkRuntimeElements
All of them match the consumer attributes:
...
Las dos secciones siguientes son formas de configurar las comparativas con más de una variante de producto.
Utiliza missingDimensionStrategy
La especificación de missingDimensionStrategy
en el defaultConfig
del módulo :macrobenchmark
le indica al sistema de compilación que recurra a la dimensión de variantes. Especifica qué dimensiones usar si no las encuentras en el módulo.
En el siguiente ejemplo, se usa la variante production
como dimensión predeterminada:
Kotlin
defaultConfig { missingDimensionStrategy("environment", "production") }
Groovy
defaultConfig { missingDimensionStrategy "environment", "production" }
De esta manera, el módulo :macrobenchmark
solo puede compilar y comparar las variantes de productos especificadas, lo que es útil si sabes que solo una variante de producto tiene la configuración adecuada para obtener comparativas.
Define variantes de producto en el módulo :macrobenchmark
Si deseas compilar y comparar otras variantes de producto, defínelas en el módulo :macrobenchmark
. Especifícala del mismo modo que en el módulo :app
, pero solo asigna productFlavors
a una dimension
. No se requiere ningún otro parámetro de configuración:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
Una vez definido y sincronizado el proyecto, elige la variante de compilación relevante del panel Build Variants, como se muestra en la Figura 4:
Para obtener más información, consulta Cómo corregir errores de compilación relacionados con la coincidencia de variantes.
Cómo crear una clase de macrocomparativas
Las pruebas de comparativas se proporcionan a través de la API de la regla MacrobenchmarkRule
de JUnit4 en la biblioteca de Macrobenchmark. Dicha biblioteca contiene un método measureRepeated
que te permite especificar varias condiciones para ejecutar y comparar la app de destino.
Como mínimo, debes especificar el packageName
de la app de destino, las metrics
que deseas medir y la cantidad de iterations
que debe ejecutar la comparativa.
Kotlin
@LargeTest @RunWith(AndroidJUnit4::class) class SampleStartupBenchmark { @get:Rule val benchmarkRule = MacrobenchmarkRule() @Test fun startup() = benchmarkRule.measureRepeated( packageName = TARGET_PACKAGE, metrics = listOf(StartupTimingMetric()), iterations = DEFAULT_ITERATIONS, setupBlock = { // Press home button before each run to ensure the starting activity isn't visible. pressHome() } ) { // starts default launch activity startActivityAndWait() } }
Java
@LargeTest @RunWith(AndroidJUnit4.class) public class SampleStartupBenchmark { @Rule public MacrobenchmarkRule benchmarkRule = new MacrobenchmarkRule(); @Test public void startup() { benchmarkRule.measureRepeated( /* packageName */ TARGET_PACKAGE, /* metrics */ Arrays.asList(new StartupTimingMetric()), /* iterations */ 5, /* measureBlock */ scope -> { // starts default launch activity scope.startActivityAndWait(); return Unit.INSTANCE; } ); } }
Si deseas conocer todas las opciones para personalizar tus comparativas, consulta la sección Cómo personalizar las comparativas.
Cómo ejecutar las comparativas
Ejecuta la prueba desde Android Studio para medir el rendimiento de la app en tu dispositivo. Puedes ejecutar las comparativas de la misma manera que ejecutas cualquier otra @Test
con la acción del margen junto a tu clase o método de prueba, como se muestra en la Figura 5.
Puedes ejecutar todas las comparativas en un módulo de Gradle desde la línea de comandos ejecutando el comando connectedCheck
:
./gradlew :macrobenchmark:connectedCheck
Puedes realizar una sola prueba ejecutando lo siguiente:
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup
Consulta Cómo obtener comparativas en integración continua para obtener información sobre la ejecución y supervisión de comparativas en integración continua.
Resultados de comparativas
Después de generar una comparativa con éxito, las métricas se muestran directamente en Android Studio y como resultados del uso de CI en un archivo JSON. Cada iteración medida captura un registro del sistema diferente. Para abrir estos resultados de seguimiento, haz clic en los vínculos del panel Test Results, como se muestra en la Figura 6:
Cuando se carga el registro, Android Studio te solicita que selecciones el proceso a analizar. La selección se prepropaga con el proceso de la app de destino, como se muestra en la Figura 7:
Una vez cargado el archivo de registro, Studio muestra los resultados en el Generador de perfiles de CPU :
Los informes de JSON y cualquier seguimiento 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/
Cómo acceder manualmente a los archivos de registro
Si quieres usar Perfetto para analizar un archivo de registro, se requieren pasos adicionales. Perfetto te permite inspeccionar todos los procesos que se realizan en el dispositivo durante el registro. En cambio, el Generador de perfiles de CPU de Android Studio limita la inspección a un único proceso.
Si invocas las pruebas desde Android Studio o desde la línea de comandos de Gradle, los archivos de registro 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/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
Cuando tengas el archivo de registro en tu sistema host, podrás abrirlo en Android Studio seleccionando File > Open en el menú. Esta opción muestra la vista de la herramienta del generador de perfiles que se proporcionó en la sección anterior.
Errores de configuración
Si la app está mal configurada (es depurable o no permite que se generen perfiles), Macrobenchmark mostrará un error, en lugar de informar una medición incorrecta o incompleta. Puedes suprimir esos errores con el argumento androidx.benchmark.suppressErrors
.
Macrobenchmark también muestra errores cuando se intenta medir un emulador o si el dispositivo tiene poca batería, lo que puede comprometer la disponibilidad principal y la velocidad del reloj.
Cómo personalizar las comparativas
La función measureRepeated
acepta varios parámetros que influyen en qué métricas recopila la biblioteca, cómo se inicia y compila tu app, y cuántas iteraciones ejecutará la comparativa.
Captura las métricas
Las métricas son el tipo principal de información que se extrae de tus comparativas. Las métricas disponibles son las siguientes:
Para obtener más información sobre las métricas, consulta Cómo capturar métricas de Macrobenchmark.
Mejora los datos de registro con eventos personalizados
Podría resultarte útil instrumentar tu app con eventos de registro personalizados, que se muestren con el resto del informe de registro y puedan ayudar a identificar problemas específicos de tu app. Si quieres obtener más información sobre la creación de eventos de registro personalizados, consulta el artículo Cómo definir eventos personalizados.
CompilationMode
Las macrocomparativas pueden especificar un CompilationMode
, que define cuánto de la app se debe compilar previamente desde el código de bytes DEX (el formato de código de bytes dentro de un APK) al código máquina (similar a C++ ya compilado).
De forma predeterminada, las macrocomparativas se ejecutan con CompilationMode.DEFAULT
, que instala un perfil de Baseline (si está disponible) en Android 7 (nivel de API 24) y versiones posteriores.
Si usas Android 6 (nivel de API 23) o versiones anteriores, el modo de compilación compila por completo el APK como el comportamiento predeterminado del sistema.
Puedes instalar un perfil de Baseline si la app de destino contiene este tipo de perfil y la biblioteca de ProfileInstaller
.
En Android 7 y versiones posteriores, puedes personalizar el CompilationMode
para que afecte la cantidad de compilación previa en el dispositivo, y así imitar diferentes niveles de compilación anticipada (AOT) o almacenamiento en caché de JIT. Consulta CompilationMode.Full
, CompilationMode.Partial
, CompilationMode.None
y CompilationMode.Ignore
.
Esta función se basa en comandos de compilación de ART. Para garantizar que no haya interferencias entre las comparativas, cada una borrará los datos de perfil antes de comenzar.
StartupMode
Para iniciar una actividad, puedes pasar un modo de inicio predefinido: COLD
, WARM
o HOT
. Este parámetro cambia la manera en la que se inicia la actividad y el estado del proceso al comienzo de la prueba.
Para obtener más información sobre los tipos de inicio, consulta Tiempo de inicio de la app.
Ejemplos
Hay un proyecto de muestra disponible en la Muestra de macrocomparativas del repositorio en GitHub.
Envía comentarios
Si deseas informar errores o enviar solicitudes de funciones de Jetpack Macrobenchmark, consulta la Herramienta de seguimiento de errores pública.
Recomendaciones para ti
- Nota: El texto del vínculo se muestra cuando JavaScript está desactivado
- Cómo capturar métricas de macrocomparativas
- Cómo crear perfiles de Baseline {:#creating-profile-rules}
- Cómo automatizar la medición con la biblioteca de Macrobenchmark {:#measuring-optimization}