Use a biblioteca Macrobenchmark para testar casos de uso maiores do
app, incluindo a inicialização e manipulações complexas de interface, como rolar uma
RecyclerView
ou mostrar animações. Se você quiser testar áreas menores do
código, consulte a biblioteca Microbenchmark. Esta página mostra como configurar
a biblioteca Macrobenchmark.
A biblioteca gera resultados comparativos no console do Android Studio e em um arquivo JSON com mais detalhes. Ela também fornece arquivos de rastreamento que podem ser carregados e analisados no Android Studio.
Use a biblioteca Macrobenchmark em um ambiente de integração contínua (CI), conforme descrito em Comparação na integração contínua.
Você pode usar a Macrobenchmark para gerar perfis de referência. Primeiro, configure a biblioteca Macrobenchmark e, em seguida, crie um perfil de referência.
Configuração do projeto
Recomendamos que você use a Macrobenchmark com a versão mais recente do Android Studio para aproveitar os recursos do ambiente de desenvolvimento integrado à Macrobenchmark.
Configurar o módulo Macrobenchmark
A biblioteca Macrobenchmark exige um módulo
com.android.test
separado do código do app, responsável por executar os testes
que medem o desempenho dele.
No Android Studio, há um modelo disponível para simplificar a configuração do módulo da biblioteca Macrobenchmark. O modelo de módulo de comparação cria automaticamente um módulo no projeto para medir o app criado por um módulo, incluindo um exemplo de inicialização de comparação.
Para usar o modelo e criar um novo módulo, siga estas etapas:
Clique com o botão direito do mouse no seu projeto ou módulo no painel Project do Android Studio e selecione em New > Module.
Selecione Benchmark no painel Templates. É possível personalizar o app de destino (o app que vai ser comparado) e também o nome do pacote e do novo módulo da Macrobenchmark.
Clique em Finish.
Figura 1. Modelo de módulo de comparação
Configurar o app
Para comparar um app, conhecido como destino da Macrobenchmark, ele precisa ser
profileable
, o que permite ler informações detalhadas sobre o trace sem
afetar o desempenho. O assistente de módulo adiciona a tag <profileable>
automaticamente ao arquivo AndroidManifest.xml
do app.
Confira se o app de destino inclui o
ProfilerInstaller
1.3 ou mais recente,
que a biblioteca Macrobenchmark precisa para ativar a captura de perfil, redefinir e
limpar o cache do sombreador.
Configure o app comparado para que fique o mais próximo possível da versão de lançamento
ou de produção. Defina-o como não depurável e, de preferência, com a minificação ativada, que
melhora o desempenho. Normalmente, isso é feito criando uma cópia da variante
de lançamento, que tem o mesmo desempenho, mas é assinada localmente com chaves de depuração.
Como alternativa, use initWith
para instruir o Gradle a fazer isso por você:
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 { val release = 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") } create("benchmark") { initWith(release) signingConfig = signingConfigs.getByName("debug") proguardFiles("benchmark-rules.pro") } }
Para garantir que a comparação crie e teste a variante correta do app, conforme mostrado na Figura 2, faça o seguinte:
- Faça uma sincronização com o Gradle.
- Abra o painel Build Variants.
- Selecione a variante de comparação do app e do módulo da Macrobenchmark.
Figura 2. Selecione a variante da comparação.
(Opcional) Configurar apps com vários módulos
Caso seu app tenha mais de um módulo do Gradle, confira se os scripts de build sabem
qual variante vai ser compilada. Adicione a propriedade matchingFallbacks
ao
tipo de build benchmark
dos módulos :macrobenchmark
e :app
. Os outros
módulos do Gradle podem ter a mesma configuração anterior.
Kotlin
create("benchmark") { initWith(getByName("release")) signingConfig = signingConfigs.getByName("debug") matchingFallbacks += listOf("release") }
Groovy
benchmark { initWith buildTypes.release signingConfig signingConfigs.debug matchingFallbacks = ['release'] }
Sem isso, o tipo de build benchmark
recém-adicionado faz com que o build falhe
e mostra esta mensagem de erro:
> Could not resolve project :shared.
Required by:
project :app
> No matching variant of project :shared was found.
...
Ao selecionar as variantes de build no seu projeto, escolha benchmark
para os módulos :app
e :macrobenchmark
, e release
para qualquer outro módulo no
app, conforme mostrado na Figura 3:
Figura 3. Variantes de comparação para projetos com vários módulos, com tipos de build de lançamento e de comparação selecionados.
Para mais informações, consulte Usar gerenciamento de dependências com reconhecimento de variantes.
(Opcional) Configurar variações de produtos
Se você tem diversas variações de produto definidas no app, configure o
módulo :macrobenchmark
para que ele saiba qual variação vai ser criada
e comparada.
Os exemplos nesta página estão usando as duas variações de produto no
módulo :app
: demo
e production
, conforme mostrado no snippet a seguir:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" // ... } create("production") { dimension = "environment" // ... } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' // ... } production { dimension 'environment' // ... } }
Sem essa configuração, você pode receber um erro de build semelhante ao que acontece com vários módulos 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:
...
As duas seções a seguir são maneiras de configurar a comparação com diversas variações de produto.
Usar missingDimensionStrategy
Especificar missingDimensionStrategy
no defaultConfig
do módulo
:macrobenchmark
instrui o sistema de build a usar a dimensão
de variações como substituta. Especifique quais dimensões usar se você não as encontrar no módulo.
No exemplo a seguir, a variação production
é usada como a dimensão
padrão:
Kotlin
defaultConfig { missingDimensionStrategy("environment", "production") }
Groovy
defaultConfig { missingDimensionStrategy "environment", "production" }
Dessa forma, o módulo :macrobenchmark
só pode criar e comparar a
variação de produto especificada, o que é útil quando você sabe que apenas uma delas
tem a configuração adequada para comparação.
Definir variações de produtos no módulo :macrobenchmark
Para criar e comparar outras variações de produto, defina-as no
módulo :macrobenchmark
. Especifique-as de maneira semelhante ao módulo :app
, mas atribua
apenas a productFlavors
a uma dimension
. Nenhuma outra configuração é necessária:
Kotlin
flavorDimensions += "environment" productFlavors { create("demo") { dimension = "environment" } create("production") { dimension = "environment" } }
Groovy
flavorDimensions 'environment' productFlavors { demo { dimension 'environment' } production { dimension 'environment' } }
Depois de definir e sincronizar o projeto, escolha a variante de build relevante no painel Build Variants, conforme mostrado na Figura 4:
Figura 4. Variantes de comparação do projeto com variações de produto mostrando as opções "productionBenchmark" e "release" selecionadas.
Para saber mais, consulte Resolver erros de build relacionados à correspondência de variantes.
Criar uma classe de Macrobenchmark
O teste de comparação é fornecido pela API de regra MacrobenchmarkRule
do JUnit4
na biblioteca Macrobenchmark. Ele contém um método measureRepeated
que permite especificar várias condições de execução e comparar o app de
destino.
É necessário especificar pelo menos o packageName
do app de destino, quais
metrics
você quer medir e quantas iterations
a comparação precisa executar.
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; } ); } }
Para conferir todas as opções de personalização da sua comparação, consulte a seção Personalizar as comparações.
Executar a comparação
Faça o teste no Android Studio para medir o desempenho do app
no dispositivo. É possível executar as comparações da mesma forma que qualquer outro
@Test
usando a ação de gutter ao lado da classe ou do método de teste, como mostrado na
Figura 5.
Figura 5. Executar a Macrobenchmark com ação de gutter ao lado da classe de teste
Também é possível fazer todas as comparações em um módulo do Gradle na linha de comando
usando o comando connectedCheck
:
./gradlew :macrobenchmark:connectedCheck
Você pode fazer um único teste executando o seguinte:
./gradlew :macrobenchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.macrobenchmark.startup.SampleStartupBenchmark#startup
.
Consulte Comparação em integração contínua para informações sobre como executar e monitorar comparações na integração contínua.
Resultados da comparação
Após a execução da comparação, as métricas são mostradas diretamente no Android Studio e são geradas para uso da CI em um arquivo JSON. Cada iteração medida captura um rastreamento do sistema separado. Você pode abrir esses resultados de rastreamento clicando nos links no painel Test Results, conforme mostrado na Figura 6:
Figura 6. Resultados de inicialização da Macrobenchmark
Quando o rastreamento é carregado, o Android Studio pede que você selecione o processo a ser analisado. A seleção é pré-preenchida com o processo do app de destino, conforme mostrado na Figura 7:
Figura 7. Seleção de processos de rastreamento do Studio
Após o arquivo de rastreamento ser carregado, o Studio mostra os resultados na ferramenta CPU Profiler:
Figura 8. Rastreamento do Studio.
Os relatórios JSON e todos os rastros de criação de perfil também são copiados automaticamente do dispositivo para o host. Eles são gravados na máquina host no seguinte local:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/
Acessar arquivos de rastreamento manualmente
Para usar a ferramenta Perfetto para analisar um arquivo de rastreamento, outras etapas precisam ser seguidas. O Perfetto possibilita inspecionar todos os processos que ocorrem em todo o dispositivo durante o rastreamento, enquanto o CPU Profiler do Android Studio limita a inspeção a um único processo.
Se você invocar os testes no Android Studio ou na linha de comando do Gradle, os arquivos de rastreamento serão copiados automaticamente do dispositivo para o host. Eles são gravados na máquina host no seguinte local:
project_root/module/build/outputs/connected_android_test_additional_output/debugAndroidTest/connected/device_id/TrivialStartupBenchmark_startup[mode=COLD]_iter002.perfetto-trace
Quando você tiver o arquivo de rastreamento no sistema host, poderá abri-lo no Android Studio com File > Open no menu. A tela da ferramenta do criador de perfil mostrada na seção anterior vai aparecer.
Erros de configuração
Se o app estiver configurado incorretamente (por exemplo, se for depurável ou não estiver relacionado à criação de perfil), a Macrobenchmark vai retornar
um erro, em vez de relatar uma medição incorreta ou incompleta. É possível
suprimir esses erros usando o argumento
androidx.benchmark.suppressErrors
.
A Macrobenchmark também retorna erros ao tentar medir um emulador ou em um dispositivo com bateria fraca, o que pode comprometer a disponibilidade de núcleos e a velocidade do clock.
Personalizar as comparações
A função measureRepeated
aceita vários parâmetros que influenciam
quais métricas a biblioteca coleta, como o app é iniciado e compilado ou quantas
iterações a comparação executa.
Capturar as métricas
As métricas são o principal tipo de informação extraída das comparações. As seguintes métricas estão disponíveis:
Para mais informações sobre métricas, consulte Capturar métricas da Macrobenchmark.
Melhorar os dados de rastreamento com eventos personalizados
Pode ser útil instrumentar o app com eventos de rastreamento personalizados, que são mostrados com o restante do relatório de rastreamento e podem ajudar a apontar problemas específicos do app. Para saber mais sobre como criar eventos de rastreamento personalizados, consulte o guia Definir eventos personalizados.
CompilationMode
As Macrobenchmarks podem especificar uma classe CompilationMode
, que define quanto do
app precisa ser pré-compilado do bytecode DEX (o formato de bytecode dentro de um
APK) para código de máquina (semelhante à linguagem C++ pré-compilada).
Por padrão, as Macrobenchmarks são executadas com o CompilationMode.DEFAULT
, que
instala um perfil de referência, se disponível, no Android 7 (nível 24 da API) e versões mais recentes.
Se você estiver usando o Android 6 (nível 23 da API) ou uma versão anterior, o modo de compilação
compila o APK completamente como o comportamento padrão do sistema.
Você pode instalar um perfil de referência se o app de destino tiver um perfil de
referência e usar a biblioteca ProfileInstaller
.
No Android 7 e versões mais recentes, é possível personalizar o CompilationMode
para afetar a
quantidade de pré-compilação no dispositivo e imitar diferentes níveis de compilação
antecipada (AOT, na sigla em inglês) ou armazenamento em cache JIT. Consulte CompilationMode.Full
,
CompilationMode.Partial
, CompilationMode.None
e
CompilationMode.Ignore
.
Esse recurso é criado com base em comandos de compilação do ART. Cada comparação limpa os dados de perfil antes de começar para garantir a não interferência entre elas.
StartupMode
Para iniciar uma atividade, é possível transmitir um modo de inicialização predefinido:
COLD
, WARM
ouHOT
. Esse parâmetro muda a forma como a atividade
é iniciada e o estado do processo no início do teste.
Para saber mais sobre os tipos de inicialização, consulte Tempo de inicialização do app.
Trechos
Um projeto de exemplo está disponível no Exemplo de Macrobenchmark do repositório no GitHub.
Enviar feedback
Para comunicar problemas ou enviar solicitações de recursos para a MacroBenchmark Jetpack, consulte o Issue Tracker público.
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Capturar métricas de Macrobenchmark
- Criar perfis de referência {:#creating-profile-rules}
- Automatizar a medição com a biblioteca Macrobenchmark {:#measuring-optimization}