Medición del rendimiento
Perfiladores, trazas y benchmarks
Medición del rendimiento es una lección gratuita de Android Academy en CoddyKit. Esta es la lección 1 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Android Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Android Academy incluye 4 lecciones en total.
Mida antes de optimizar
La regla de oro del trabajo de rendimiento es: mida primero, nunca adivine. La intuición humana sobre qué es lento casi siempre se equivoca.
En esta lección aprenderá a utilizar las herramientas que Android proporciona para ver el rendimiento: los perfiladores, las trazas del sistema y los microbenchmarks. Cuando pueda medir, cada optimización se convertirá en una decisión basada en datos en lugar de una suposición.
- Los perfiladores muestran la CPU, la memoria y la energía en tiempo real.
- Las trazas del sistema revelan exactamente en qué se invierte el tiempo de cada fotograma.
- Los benchmarks proporcionan cifras reproducibles que puede comparar entre compilaciones.
El presupuesto de 16 ms por fotograma
En una pantalla de 60 Hz, el sistema dibuja un fotograma nuevo cada 16.67 ms. Si su aplicación no puede preparar un fotograma en ese intervalo, se pierde y los usuarios perciben jank (tirones). En los dispositivos de 120 Hz, el presupuesto se reduce a unos 8 ms.
El trabajo de rendimiento consiste realmente en mantenerse dentro de este presupuesto. El comentario siguiente muestra el cálculo que debe tener presente.
// Frame budget math
// 60 Hz -> 1000ms / 60 = 16.67ms per frame
// 90 Hz -> 1000ms / 90 = 11.11ms per frame
// 120 Hz -> 1000ms / 120 = 8.33ms per frame
//
// Exceed the budget on the UI thread = a dropped frame = visible jank.
fun frameBudgetMs(refreshHz: Int): Double = 1000.0 / refreshHz
fun main() {
println("60Hz -> %.2f ms".format(frameBudgetMs(60)))
println("120Hz -> %.2f ms".format(frameBudgetMs(120)))
}Android Studio Profiler
Android Studio Profiler (View > Tool Windows > Profiler) se conecta a una aplicación en ejecución y muestra líneas de tiempo en directo para la CPU, la memoria, la energía y la red.
- CPU: registre trazas de métodos y trazas del sistema para encontrar las rutas de código críticas.
- Memoria: supervise las asignaciones y capture volcados del montón para encontrar fugas.
- Energía: detecte wakelocks y trabajos excesivos que agotan la batería.
Realice siempre el perfilado con una compilación de tipo release en un dispositivo real. Las compilaciones de depuración y los emuladores ofrecen cifras engañosas porque las optimizaciones están desactivadas.
Macrobenchmark para escenarios reales
La biblioteca Jetpack Macrobenchmark mide recorridos completos del usuario (inicio, desplazamiento y navegación) en un dispositivo real y proporciona métricas estables, como el tiempo de los fotogramas y el tiempo de inicio.
Escriba una prueba que inicie su aplicación y ejecute un flujo; la biblioteca lo ejecuta muchas veces y le proporciona los valores de la mediana y del percentil 99.
@RunWith(AndroidJUnit4::class)
class StartupBenchmark {
@get:Rule val rule = MacrobenchmarkRule()
@Test
fun coldStartup() = rule.measureRepeated(
packageName = "com.example.app",
metrics = listOf(StartupTimingMetric()),
iterations = 5,
startupMode = StartupMode.COLD
) {
pressHome()
startActivityAndWait()
}
}Microbenchmark para código crítico
Cuando necesite saber qué tan rápida es una sola función, use la biblioteca Microbenchmark. Ejecuta su código en un bucle ajustado, calienta el JIT y proporciona los nanosegundos por operación, eliminando el ruido de la medición.
Úsela para analizadores, serializadores, ordenaciones o cualquier utilidad limitada por la CPU que se invoque con frecuencia.
@RunWith(AndroidJUnit4::class)
class JsonParseBenchmark {
@get:Rule val benchmarkRule = BenchmarkRule()
@Test
fun parseLargePayload() {
val raw = loadSampleJson()
benchmarkRule.measureRepeated {
val parsed = parseUsers(raw) // code under test
// assertEquals avoids the compiler dropping the result
assertTrue(parsed.isNotEmpty())
}
}
}Trazado del sistema con Perfetto
El trazado del sistema captura lo que hizo cada subproceso y el sistema, fotograma a fotograma. El perfilador de CPU de Android Studio puede grabar uno, y también puede capturarlo con adb y abrirlo en Perfetto (ui.perfetto.dev).
Una traza muestra los temidos fotogramas rojos, el trabajo del subproceso principal y el tiempo empleado en la GPU. Es la mejor herramienta para diagnosticar el jank.
# Record a 5-second system trace from the command line
adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto-trace \
-t 5s sched freq idle am wm gfx view
# Pull it to your machine, then open in https://ui.perfetto.dev
adb pull /data/misc/perfetto-traces/trace.perfetto-traceSecciones de traza personalizadas
De forma predeterminada, las trazas muestran el trabajo del framework. Para etiquetar su propio código, inclúyalo en una sección de traza con nombre. Estos nombres aparecen como bloques etiquetados en Perfetto, lo que facilita localizar los puntos críticos.
Use la API de androidx.tracing para que las secciones aparezcan tanto en las trazas de depuración como en las de referencia.
import androidx.tracing.trace
fun loadDashboard(repo: Repo): Dashboard {
return trace("loadDashboard") {
val user = trace("fetchUser") { repo.user() }
val feed = trace("fetchFeed") { repo.feed() }
Dashboard(user, feed)
}
}
// In Perfetto you will now see named slices:
// loadDashboard > fetchUser, fetchFeedSeguimiento de fotogramas perdidos en tiempo de ejecución
No siempre tendrá un perfilador conectado. JankStats es una biblioteca de Jetpack que informa de los fotogramas con jank desde la propia aplicación en ejecución, para que pueda registrarlos o enviar agregados a sus análisis.
Se integra con la ventana y le devuelve una llamada cada vez que un fotograma supera su presupuesto.
val jankStats = JankStats.createAndTrack(window) { frameData ->
if (frameData.isJank) {
Log.w("Jank", "Janky frame: ${frameData.frameDurationUiNanos} ns")
analytics.logJank(frameData.frameDurationUiNanos)
}
}
// Pause/resume with your screen lifecycle
override fun onResume() { super.onResume(); jankStats.isTrackingEnabled = true }
override fun onPause() { super.onPause(); jankStats.isTrackingEnabled = false }Cómo leer las cifras: percentiles
Un solo promedio oculta los problemas. Si el fotograma medio tarda 10 ms, pero el percentil 99 es de 40 ms, el 1 % de los fotogramas tiene jank y los usuarios lo perciben. Consulte siempre P50, P90, P99, no solo la media.
Los benchmarks le proporcionan estos valores. El ejemplo auxiliar siguiente muestra la idea con muestras de fotogramas sin procesar.
fun percentile(samplesMs: List<Double>, p: Int): Double {
val sorted = samplesMs.sorted()
val index = ((p / 100.0) * (sorted.size - 1)).toInt()
return sorted[index]
}
fun main() {
val frames = listOf(8.0, 9.0, 10.0, 9.5, 11.0, 40.0, 9.0, 10.5)
println("P50 = %.1f ms".format(percentile(frames, 50)))
println("P99 = %.1f ms".format(percentile(frames, 99)))
}Un flujo de medición reproducible
Las cifras fiables se obtienen mediante un proceso disciplinado. Siga esta lista de comprobación cada vez:
- Use una compilación release / no depurable (con R8 activado).
- Ejecute la prueba en un dispositivo físico, conectado a la corriente y con un estado térmico estable.
- Repita el escenario varias veces e informe de la mediana.
- Cambie una sola cosa cada vez y vuelva a medir.
- Compare con una línea base guardada para poder demostrar la mejora.
Si omite estos pasos, perseguirá el ruido en lugar de solucionar problemas reales.
En qué se emplea realmente el tiempo
La mayor parte del jank de Android procede de un pequeño conjunto de causas. Conocerlas le indica hacia dónde dirigir sus herramientas:
- Trabajo en el subproceso principal: operaciones de disco, red o JSON en el subproceso de interfaz.
- Recomposición excesiva: Compose vuelve a dibujar mucho más de lo necesario.
- Oleada de asignaciones: pausas de la recolección de basura.
- Pasadas de diseño: diseños profundamente anidados o medidos repetidamente.
Las próximas lecciones de este curso abordan directamente la recomposición, las fugas de memoria y el inicio. La medición es lo que le indica cuál debe solucionar primero.
Comprobación rápida
Quiere obtener una medición estable y reproducible del tiempo que tarda el inicio en frío de su aplicación en un dispositivo real durante varias ejecuciones. ¿Qué herramienta es la más adecuada?
Repaso: ahora puede medir
Ha aprendido a hacer que el rendimiento sea visible antes de cambiar nada:
- El presupuesto de 16 ms por fotograma determina si la experiencia es fluida o tiene jank.
- Android Studio Profiler muestra información en directo sobre la CPU, la memoria y la energía.
- Los Macrobenchmarks y Microbenchmarks proporcionan cifras reproducibles.
- Las trazas de Perfetto y las secciones
trace()personalizadas revelan en qué se emplea el tiempo. - JankStats informa del jank desde la aplicación en ejecución.
- Lea P50/P90/P99, perfile compilaciones release en dispositivos reales y cambie una sola cosa cada vez.
A continuación aplicaremos esto a una de las principales fuentes de jank en Compose: la recomposición.
Preguntas frecuentes
¿La lección «Medición del rendimiento» es gratis?
Sí — el texto completo de «Medición del rendimiento» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Android Academy, actualiza a CoddyKit PRO. El curso de Android Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Medición del rendimiento»?
Perfiladores, trazas y benchmarks Practicas Android Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Android Academy?
No se requiere experiencia previa. Android Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 1 de 4.
¿Cuánto tiempo toma la lección «Medición del rendimiento»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Android Academy?
Sí. Cada lección de Android Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Medición del rendimiento
- Cómo controlar la recomposición
- Fugas de memoria y soluciones
- Perfiles de inicio y de referencia