Comparar perfis de referência com a biblioteca Macrobenchmark

Recomendamos usar a Jetpack Macrobenchmark para testar o desempenho de um app quando os perfis de referência estiverem ativados e usar esses resultados para uma comparação com perfis de referência desativados. Com essa abordagem, é possível medir o tempo de inicialização do app (tanto a tela inicial quanto a completa) ou o desempenho da renderização do ambiente de execução para conferir se os frames produzidos podem causar instabilidade.

Macrobenchmarks permitem controlar a compilação de pré-medição usando a API CompilationMode. Use valores de CompilationMode diferentes para comparar a performance com diferentes estados de compilação. O snippet de código abaixo mostra como usar o parâmetro CompilationMode para medir o benefício dos perfis de referência:

@RunWith(AndroidJUnit4ClassRunner::class)
class ColdStartupBenchmark {
    @get:Rule
    val benchmarkRule = MacrobenchmarkRule()

    // No ahead-of-time (AOT) compilation at all. Represents performance of a
    // fresh install on a user's device if you don't enable Baseline Profiles—
    // generally the worst case performance.
    @Test
    fun startupNoCompilation() = startup(CompilationMode.None())

    // Partial pre-compilation with Baseline Profiles. Represents performance of
    // a fresh install on a user's device.
    @Test
    fun startupPartialWithBaselineProfiles() =
        startup(CompilationMode.Partial(baselineProfileMode = BaselineProfileMode.Require))

    // Partial pre-compilation with some just-in-time (JIT) compilation.
    // Represents performance after some app usage.
    @Test
    fun startupPartialCompilation() = startup(
        CompilationMode.Partial(
            baselineProfileMode = BaselineProfileMode.Disable,
            warmupIteration = 3
        )
    )

    // Full pre-compilation. Generally not representative of real user
    // experience, but can yield more stable performance metrics by removing
    // noise from JIT compilation within benchmark runs.
    @Test
    fun startupFullCompilation() = startup(CompilationMode.Full())

    private fun startup(compilationMode: CompilationMode) = benchmarkRule.measureRepeated(
        packageName = "com.example.macrobenchmark.target",
        metrics = listOf(StartupTimingMetric()),
        compilationMode = compilationMode,
        iterations = 10,
        startupMode = StartupMode.COLD,
        setupBlock = {
            pressHome()
        }
    ) {
        // Waits for the first rendered frame, which represents time to initial display.
        startActivityAndWait()

        // Waits for content to be visible, which represents time to fully drawn.
        device.wait(Until.hasObject(By.res("my-content")), 5_000)
    }
}

Na captura de tela a seguir, você pode conferir os resultados diretamente no Android Studio para o app de exemplo Now in Android (link em inglês) executado no Google Pixel 7. Os resultados mostram que a inicialização do app é mais rápida ao usar perfis de referência (229,0ms) quando comparado a nenhuma compilação (324,8ms).

Resultados de ColdstartupBenchmark
Figura 1. Resultados de ColdStartupBenchmark mostrando o tempo para abrir a tela inicial sem compilação (324ms), com compilação completa (315ms), compilação parcial (312ms) e perfis de referência (229ms).

O exemplo anterior mostra os resultados da inicialização do app capturados com StartupTimingMetric, mas há outras métricas importantes que precisam ser consideradas, como FrameTimingMetric. Para mais informações sobre todos os tipos de métricas, consulte Capturar métricas de Macrobenchmark.

Tempo para exibição total

O exemplo anterior mede o tempo para exibição inicial (TTID, na sigla em inglês), que é o tempo que o app leva para produzir o primeiro frame. No entanto, isso não reflete necessariamente o tempo até o usuário começar a interagir com o app. A métrica tempo para exibição total (TTFD, na sigla em inglês) é mais útil para medir e otimizar os caminhos de código necessários para ter um estado totalmente utilizável do app.

Recomendamos a otimização para TTID e TTFD, porque ambas são importantes. Um TTID baixo ajuda o usuário a saber que o app está sendo iniciado. Manter um TTFD breve é importante para garantir que o usuário possa interagir com o app rapidamente.

Para conferir estratégias de geração de relatórios quando a interface do app está totalmente renderizada, consulte Melhorar a precisão da marcação do tempo de inicialização.

  • Observação: o texto do link aparece quando o JavaScript está desativado.
  • [Como criar uma comparação da Macrobenchmark][11]
  • [Capturar métricas de Macrobenchmark][12]
  • [Otimização e análise de inicialização do app {:#app-startup-analysis-optimization}][13]