Usa la biblioteca de Macrobenchmark para probar los casos de uso más grandes de tu aplicación, incluido su inicio y las manipulaciones de IU complejas, como desplazarse por una RecyclerView
o ejecutar animaciones. Si quieres probar partes más pequeñas de tu código, consulta la biblioteca de Microcomparativas.
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 macrocomparativas en un entorno de integración continua (CI) tal como se describe en Cómo ejecutar comparativas en la integración continua.
Los perfiles de Baseline se pueden generar con macrocomparativas. Sigue la guía que se encuentra a continuación para configurar la Biblioteca de macrocomparativas y, luego, crea un perfil de modelo de referencia.
Configuración del proyecto
Te recomendamos que uses Macrobenchmark con la versión más reciente de Android Studio, ya que hay funciones nuevas en esa versión 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 a fin de 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, haz clic en 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 macrocomparativas.
Haz clic en Finish.
Configura la aplicación
Para obtener comparativas de una app (denominada el objetivo de la macrocomparativa), 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.
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:
Groovy
buildTypes { release { minifyEnabled true shrinkResources true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } benchmark { initWith buildTypes.release signingConfig signingConfigs.debug proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'benchmark-rules.pro' } }
Kotlin
buildTypes { getByName("release") { isMinifyEnabled = true isShrinkResources = true proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt")) } create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") } }
Realiza una sincronización de Gradle, abre el panel Build Variants en el lado izquierdo y selecciona la variante de comparativas de la app y del módulo de macrocomparativas. De esta manera, te aseguras de que con la ejecución de las comparativas se compile y se pruebe la variante correcta de tu app.
(Opcional) Configura una aplicación con varios módulos
Si tu app tiene más de un módulo de Gradle, debes asegurarte de que las secuencias de comandos de compilación sepan la variante de compilación que deben compilar. De lo contrario, el buildType 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.
...
Para solucionar el problema, agrega la propiedad matchingFallbacks
al buildType benchmark
de los módulos :macrobenchmark
y :app
. El resto de los módulos de Gradle puede tener la misma configuración que antes.
Groovy
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf('release') }
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 siguiente imagen:
Si quieres obtener más información, consulta el artículo para administrar dependencias con reconocimiento de variantes.
(Opcional) Configura las variantes de producto
Si configuraste más de una variante de producto en la app, debes configurar el módulo :macrobenchmark
para que sepa qué tipo de variante compilar y comparar. 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:
...
Para esta guía, usaremos las dos variantes de producto de nuestro módulo :app
(demo
y production
), como puedes ver en el siguiente fragmento:
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
Hay dos formas de configurar las comparativas con más de una variante de producto:
Usa 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. Si las dimensiones no se encuentran en el módulo, debes especificar cuáles buscar. En el siguiente ejemplo, se usa la variante production
como dimensión predeterminada:
Groovy
defaultConfig { missingDimensionStrategy "environment", "production" }
Kotlin
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 las variantes de productos en el módulo :macrobenchmark
Si deseas compilar y comparar otras variantes de producto, debes definirlas en el módulo :macrobenchmark
. Especifícala del mismo modo que en el módulo :app
, pero solo asigna productFlavors
a dimension
; no se requieren otras opciones de configuración:
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
Una vez definido y sincronizado el proyecto, elige la variante de compilación que desees desde el panel Build Variants:
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 mediante 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 aplicación de destino.
Como mínimo, debes especificar el packageName
de la aplicación 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 = 5, 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 las comparativas, consulta la sección Cómo personalizar las comparativas.
Cómo ejecutar las comparativas
Ejecuta la prueba desde Android Studio a fin de medir el rendimiento de la app en tu dispositivo. Puedes ejecutar las comparativas como lo harías con cualquier otra @Test
con la acción del margen junto a tu clase o método de prueba, como se muestra en la siguiente imagen.
Puedes ejecutar todas las comparativas en un módulo de Gradle desde la línea de comandos mediante la ejecución del comando connectedCheck:
./gradlew :macrobenchmark:connectedCheck
También puedes ejecutar una sola prueba:
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup
Consulta la sección Comparativas en CI a fin de obtener información para ejecutar y supervisar 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 registros de resultado, haz clic en uno de los vínculos que se incluyen en el panel Test Results, como se muestra en la siguiente imagen.
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 a continuación:
Una vez cargado el archivo de registro, Studio muestra los resultados en la herramienta del 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:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Accede a los archivos de registro de forma manual
Si deseas utilizar la herramienta Perfetto para analizar un archivo de registro, debes seguir algunos 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 con la línea de comandos de Gradle, los archivos de registro se copian automáticamente del dispositivo al host. Estos están escritos en la máquina anfitrión en la siguiente string:
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, puedes abrirlo en Android Studio con las opciones File > Open del 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
.
Además, se arrojan errores cuando se intenta medir un emulador o si el dispositivo tiene poca batería, dado que se podría 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 aplicación, y cuántas iteraciones ejecutará la comparativa.
Cómo capturar las métricas
Las métricas son el tipo principal de información que se extrae de tus comparativas.
Las opciones disponibles son StartupTimingMetric
, FrameTimingMetric
y TraceSectionMetric
. Si deseas obtener más información sobre ellas, consulta la página Cómo capturar las métricas.
Cómo mejorar los datos de registro con eventos personalizados
Te puede resultar útil instrumentar la aplicación con eventos de registro personalizados, que se muestran con el resto del informe de registro y pueden 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 la guía 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 aplicación 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, a fin de imitar diferentes niveles de compilación anticipada (AOT) o almacenamiento en caché de JIT. Consulta CompilationMode.Full
, CompilationMode.Partial
y CompilationMode.None
.
Esta funcionalidad 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
A fin de iniciar una actividad, puedes pasar un modo de inicio predefinido (que puede ser COLD
, WARM
o HOT
). Este parámetro cambia la forma en que se inicia la actividad así como el estado del proceso al comienzo de la prueba.
Si quieres obtener más información sobre los tipos de inicio, consulta la documentación de inicio de Android Vitals.
Ejemplos
En GitHub, encontrarás un proyecto de ejemplo en el repositorio android/performance-samples.
Cómo enviar comentarios
Si deseas informar errores o enviar solicitudes de funciones de Jetpack Macrobenchmark, consulta la Herramienta de seguimiento de errores pública.