Para aprender a usar a biblioteca Microbenchmark adicionando mudanças no código do aplicativo, consulte a seção Guia de início rápido. Para saber como concluir uma configuração completa com mudanças mais complicadas na base de código, consulte a seção Configuração completa do projeto.
Guia de início rápido
Esta seção mostra como testar as comparações e executar medições únicas sem ter que mover o código para os módulos. Para que os resultados de desempenho sejam precisos, estas etapas envolvem desativar a depuração no app. Portanto, mantenha uma cópia local de trabalho sem confirmar as mudanças no sistema de controle de origem.
Para realizar uma comparação única, siga estas etapas:
Adicione a biblioteca ao arquivo
build.gradle
oubuild.gradle.kts
do módulo:Kotlin
dependencies { implementation("androidx.benchmark:benchmark-junit4:1.2.3") }
Groovy
dependencies { implementation 'androidx.benchmark:benchmark-junit4:1.2.3' }
Use uma dependência
implementation
em vez de uma dependênciaandroidTestImplementation
. Se você usarandroidTestImplementation
, as comparações não serão executadas, já que o manifesto da biblioteca não será integrado ao manifesto do app.Atualize o tipo de build
debug
para que ele não seja depurável:Kotlin
android { ... buildTypes { debug { isDebuggable = false } } }
Groovy
android { ... buildTypes { debug { debuggable false } } }
Mude
testInstrumentationRunner
paraAndroidBenchmarkRunner
:Kotlin
android { ... defaultConfig { testInstrumentationRunner = "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Groovy
android { ... defaultConfig { testInstrumentationRunner "androidx.benchmark.junit4.AndroidBenchmarkRunner" } }
Inclua uma instância de
BenchmarkRule
em um arquivo de teste no diretórioandroidTest
para adicionar a comparação. Para saber mais sobre como criar comparações, consulte Criar uma classe de Microbenchmark.O snippet de código a seguir mostra como adicionar uma comparação a um teste instrumentado:
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { BenchmarkRuleKt.measureRepeated( (Function1<BenchmarkRule.Scope, Unit>) scope -> doSomeWork() ); } } }
Para aprender a criar uma comparação, consulte Criar uma classe de Microbenchmark.
Configuração completa do projeto
Para configurar comparações frequentes, em vez de uma única,
isole as comparações em módulos. Isso garante que a configuração,
como definir debuggable
como false
, seja diferente dos testes normais.
Como a Microbenchmark executa o código diretamente, coloque o código que você quer comparar em um módulo separado do Gradle e defina a dependência nele, como mostrado na figura 1.
![estrutura do app](https://developer.android.com/static/topic/performance/images/benchmark_images/microbenchmark_modules.png?authuser=6&hl=pt)
:app
,
:microbenchmark
e :benchmarkable
do Gradle,
que permite as comparações da Microbenchmark no
módulo :benchmarkable
.Use o assistente do Android Studio para adicionar um novo módulo do Gradle. O
assistente cria um módulo pré-configurado, com um
diretório de comparação e debuggable
definido como false
.
Clique com o botão direito do mouse no seu projeto ou módulo no painel Project do Android Studio e clique em New > Module.
Selecione a opção Benchmark no painel Templates.
Selecione a Microbenchmark como tipo de módulo de comparações.
Digite "microbenchmark" como o nome do módulo.
Clique em Finish.
![Configuração de novo módulo de biblioteca](https://developer.android.com/static/topic/performance/images/benchmark_images/microbenchmark_module_giraffe.png?authuser=6&hl=pt)
Após a criação do módulo, mude o arquivo build.gradle
ou build.gradle.kts
e adicione androidTestImplementation
ao módulo que contém o código que será
comparado:
Kotlin
dependencies { // The module name might be different. androidTestImplementation(project(":benchmarkable")) }
Groovy
dependencies { // The module name might be different. androidTestImplementation project(':benchmarkable') }
Criar uma classe de Microbenchmark
As comparações são testes de instrumentação padrão. Para criar uma comparação, use a
classe BenchmarkRule
oferecida pela biblioteca. Para comparar atividades, use
ActivityScenario
ou ActivityScenarioRule
. Para comparar o código da interface,
use @UiThreadTest
.
O código a seguir apresenta uma amostra de comparação:
Kotlin
@RunWith(AndroidJUnit4::class) class SampleBenchmark { @get:Rule val benchmarkRule = BenchmarkRule() @Test fun benchmarkSomeWork() { benchmarkRule.measureRepeated { doSomeWork() } } }
Java
@RunWith(AndroidJUnit4.class) class SampleBenchmark { @Rule public BenchmarkRule benchmarkRule = new BenchmarkRule(); @Test public void benchmarkSomeWork() { final BenchmarkState state = benchmarkRule.getState(); while (state.keepRunning()) { doSomeWork(); } } }
Desativar a medição do tempo de configuração
É possível desativar a medição de tempo para as seções de código que você não quer avaliar usando o
bloco runWithTimingDisabled{}
. Essas seções geralmente representam um código
que você precisa executar em cada iteração da comparação.
Kotlin
// using random with the same seed, so that it generates the same data every run private val random = Random(0) // create the array once and just copy it in benchmarks private val unsorted = IntArray(10_000) { random.nextInt() } @Test fun benchmark_quickSort() { // ... benchmarkRule.measureRepeated { // copy the array with timing disabled to measure only the algorithm itself listToSort = runWithTimingDisabled { unsorted.copyOf() } // sort the array in place and measure how long it takes SortingAlgorithms.quickSort(listToSort) } // assert only once not to add overhead to the benchmarks assertTrue(listToSort.isSorted) }
Java
private final int[] unsorted = new int[10000]; public SampleBenchmark() { // Use random with the same seed, so that it generates the same data every // run. Random random = new Random(0); // Create the array once and copy it in benchmarks. Arrays.setAll(unsorted, (index) -> random.nextInt()); } @Test public void benchmark_quickSort() { final BenchmarkState state = benchmarkRule.getState(); int[] listToSort = new int[0]; while (state.keepRunning()) { // Copy the array with timing disabled to measure only the algorithm // itself. state.pauseTiming(); listToSort = Arrays.copyOf(unsorted, 10000); state.resumeTiming(); // Sort the array in place and measure how long it takes. SortingAlgorithms.quickSort(listToSort); } // Assert only once, not to add overhead to the benchmarks. assertTrue(SortingAlgorithmsKt.isSorted(listToSort)); }
Tente minimizar a quantidade de trabalho feito dentro do bloco measureRepeated
e dentro de runWithTimingDisabled
. O bloco measureRepeated
é executado
várias vezes e pode afetar o tempo total necessário para fazer a comparação. Se for
preciso verificar resultados de uma comparação, declare o último resultado
em vez de fazer todas as iterações.
Executar a comparação
No Android Studio, execute a comparação da mesma forma que faria com qualquer @Test
usando a
ação de gutter ao lado da classe ou do método de teste, conforme mostrado na Figura 3.
![Executar uma comparação de Microbenchmark](https://developer.android.com/static/topic/performance/images/benchmark_images/microbenchmark_run.png?authuser=6&hl=pt)
Na linha de comando, você também pode executar connectedCheck
para fazer todos os
testes do módulo especificado do Gradle:
./gradlew benchmark:connectedCheck
Ou, para executar um único teste:
./gradlew benchmark:connectedCheck -P android.testInstrumentationRunnerArguments.class=com.example.benchmark.SampleBenchmark#benchmarkSomeWork
Resultados da comparação
Após a execução de uma comparação da Microbenchmark, as métricas são mostradas diretamente no Android Studio, e um relatório de comparação completo com mais métricas e informações sobre o dispositivo é gerado no formato JSON.
![Resultados da comparação de Microbenchmark](https://developer.android.com/static/topic/performance/images/benchmark_images/microbenchmark_results.png?authuser=6&hl=pt)
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/
Por padrão, o relatório JSON é gravado no disco do dispositivo na pasta de mídias
compartilhadas externas do APK de teste, que normalmente fica localizada em
/storage/emulated/0/Android/media/**app_id**/**app_id**-benchmarkData.json
.
Erros de configuração
A biblioteca detecta as condições a seguir para garantir que o projeto e o ambiente estejam configurados de modo a apresentar uma performance precisa para a versão:
- O atributo "Debuggable" está definido como
false
. - Um dispositivo físico está sendo usado. Não há suporte a emuladores.
- A frequência do processador está bloqueada, caso o dispositivo tenha acesso root.
- O dispositivo está com um nível de bateria suficiente de pelo menos 25%.
Se alguma das condições anteriores não for respeitada, a comparação vai informar um erro para evitar medições imprecisas.
Para suprimir tipos específicos de erro, como avisos, e impedir que interrompam a
comparação, transmita o tipo de erro em uma lista separada por vírgulas ao argumento
de instrumentação androidx.benchmark.suppressErrors
.
Você pode definir isso no script do Gradle, conforme mostrado no exemplo a seguir:
Kotlin
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Groovy
android { defaultConfig { … testInstrumentationRunnerArguments["androidx.benchmark.suppressErrors"] = "DEBUGGABLE,LOW-BATTERY" } }
Também é possível suprimir erros usando a linha de comando:
$ ./gradlew :benchmark:connectedCheck -P andoidtestInstrumentationRunnerArguments.androidx.benchmark.supperssErrors=DEBUGGABLE,LOW-BATTERY
A supressão de erros permite que a comparação seja executada em uma configuração incorreta,
e a saída da comparação é renomeada intencionalmente ao adicionar o erro aos
nomes de teste. Por exemplo, executar uma comparação depurável com a
supressão no snippet anterior adiciona DEBUGGABLE_
como prefixo aos nomes dos testes.
Recomendados para você
- Observação: o texto do link aparece quando o JavaScript está desativado.
- Como criar uma comparação da Macrobenchmark
- Criar comparações da Microbenchmark sem o Gradle
- Criar perfis de referência {:#creating-profile-rules}