Projetos maiores ou aqueles que implementam uma grande quantidade de lógica de compilação personalizada podem exigir
que você examine mais detalhadamente o processo de compilação para encontrar gargalos.
Você pode fazer isso analisando quanto tempo leva para o Gradle executar cada fase do
ciclo de vida e cada tarefa de compilação. Por exemplo, se o perfil da compilação
mostra que o Gradle passa tempo demais configurando o projeto, isso pode
sugerir que é preciso retirar a lógica de compilação
personalizada da fase de configuração. 
Além disso, se a tarefa mergeDevDebugResources consome uma grande parte
do tempo de compilação, isso pode indicar que você precisa
converter suas imagens em WebP
ou desativar a análise de PNG.
Se você está usando o Android Studio 4.0 ou versão mais recente, a melhor maneira de investigar problemas de desempenho de compilação é usar o Build Analyzer.
Além disso, há duas opções de criar perfil do build fora do Android Studio:
- A ferramenta - gradle-profilerautônoma, uma ferramenta robusta para análise detalhada do seu build.
- A opção - --profiledo Gradle, uma ferramenta conveniente, disponível da linha de comando do Gradle.
Como usar a ferramenta gradle-profiler autônoma
Para encontrar a configuração de projeto com a melhor velocidade de compilação, você pode usar o Gradle profiler, uma ferramenta para coleta de informações sobre criação de perfis e comparações para builds do Gradle. O Gradle profiler permite criar cenários de compilação e executá-los múltiplas vezes, evitando grande variação entre resultados e garantindo a reprodução dos resultados.
O Modo de comparação é usado para coletar informações sobre builds limpos e incrementais, enquanto o modo de criação de perfil pode ser usado para coletar informações granulares sobre a execução, incluindo snapshots da CPU.
Algumas das configuração de projeto para comparação incluem:
- Versões do plug-in
- Versões do Gradle
- Configurações de JVM (tamanho da alocação heap, tamanho de permgen, coleta de lixo etc.)
- Número de workers do Gradle (org.gradle.workers.max)
- Opções por plug-in para otimizar ainda mais o desempenho
Primeiros passos
- Instale o gradle-profiler seguindo estas instruções
- Execute: gradle-profiler --benchmark --project-dir <root-project> :app:assembleDebug
Isso vai comparar um build totalmente atualizado, porque o --benchmark executa a
tarefa múltiplas vezes sem mudar o projeto entre elas. Depois, é gerado
um relatório HTML sob o diretório profile-out/, mostrando os
tempos de compilação.
Há outros cenários que podem ser mais úteis para comparar:
- Mudanças de código no corpo de um método em uma classe em que você faz a maior parte do trabalho.
- Mudanças de API em um módulo usado em todo o projeto. Embora seja menos frequente que as alterações do código, isso tem um impacto maior e é útil para avaliações.
- Edições de layout para simular a iteração no trabalho da IU.
- Edições de string para simular o trabalho com translação.
- Builds limpos para simular mudanças na próprio build (por exemplo, atualização do
Plug-in do Android para Gradle, atualização do Gradle ou edições no seu código de compilação
em buildSrc).
Para comparar esses casos de uso, crie um cenário que será
usado para impulsionar a execução do gradle-profiler e que aplica as mudanças
adequadas às suas fontes. Veja alguns dos cenários comuns abaixo.
Como criar perfis com diferentes configurações de memória/CPU
Para comparar diferentes configurações de CPU e memória, é possível criar
vários cenários que usam valores diferentes para org.gradle.jvmargs. Por
exemplo, você pode criar cenários:
# <root-project>/scenarios.txt
clean_build_2gb_4workers {
    tasks = [":app:assembleDebug"]
    gradle-args = ["--max-workers=4"]
    jvm-args = ["-Xmx2048m"]
    cleanup-tasks = ["clean"]
}
clean_build_parallelGC {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-XX:+UseParallelGC"]
    cleanup-tasks = ["clean"]
}
clean_build_G1GC_4gb {
    tasks = [":app:assembleDebug"]
    jvm-args = ["-Xmx4096m", "-XX:+UseG1GC"]
    cleanup-tasks = ["clean"]
}
A execução de gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt
executará três cenários, e será possível comparar o tempo de
:app:assembleDebug em cada uma dessas configurações.
Como criar perfis de diferentes versões do plug-in Gradle
Para descobrir como a mudança da versão do plug-in Gradle afeta os tempos de compilação, crie um cenário para fins de comparação. Isso requer alguma preparação para tornar a versão do plug-in injetável a partir do cenário. Mude seu build.gradle raiz:
# <root-project>/build.gradle
buildscript {
    def agpVersion = providers.systemProperty("agpVersion").forUseAtConfigurationTime().orNull ?: '4.1.0'
    ext.kotlin = providers.systemProperty('kotlinVersion').forUseAtConfigurationTime().orNull ?: '1.4.0'
    dependencies {
        classpath "com.android.tools.build:gradle:$agpVersion"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin"
    }
}
Agora você pode especificar as versões do Plug-in do Android para Gradle e do Kotlin para Gradle no arquivo de cenários e adicionar um novo método aos arquivos de origem:
# <root-project>/scenarios.txt
non_abi_change_agp4.1.0_kotlin1.4.10 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.1.0"
      "kotlinVersion" = "1.4.10"
}
non_abi_change_agp4.2.0_kotlin1.4.20 {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    System-properties {
      "agpVersion" = "4.2.0-alpha16"
      "kotlinVersion" = "1.4.20"
}
Como criar perfis para um build incremental
A maioria dos builds é incremental, o que torna esse um dos cenários mais importantes para o perfil. O Gradle profiler tem ampla compatibilidade com a criação de perfis de builds incrementais. Ele pode aplicar mudanças a um arquivo de origem automaticamente mudando um corpo de método, adicionando um novo método ou mudando um recurso de layout ou string. Por exemplo, é possível criar cenários incrementais como estes:
# <root-project>/scenarios.txt
non_abi_change {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}
abi_change {
    tasks = [":app:assembleDebug"]
    apply-abi-change-to = ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
}
layout_change {
    tasks = [":app:assembleDebug"]
    apply-android-layout-change-to = "app/src/main/res/your_layout_file.xml"
}
string_resource_change {
    tasks = [":app:assembleDebug"]
    apply-android-resource-value-change-to = "app/src/main/res/values/strings.xml"
}
A execução de gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt
irá gerar o relatório HTML com os dados de comparação.
É possível combinar cenários incrementais com outras configurações, como tamanho da alocação de heap, número de workers ou versão do Gradle:
# <root-project>/scenarios.txt
non_abi_change_4g {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
}
non_abi_change_4g_8workers {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx4096m"]
    gradle-args = ["--max-workers=8"]
}
non_abi_change_3g_gradle67 {
    tasks = [":app:assembleDebug"]
    apply-non-abi-change-to ["app/src/main/java/com/example/your_app/your_code_file.java,
                              "app/src/main/java/com/example/your_app/your_code_file.kt"]
    jvm-args = ["-Xmx3072m"]
    version = ["6.7"]
}
Como criar perfis para um build limpo
Para comparar um build limpo, você pode criar um cenário que será usado para conduzir a execução do gradle-profiler:
# <root-project>/scenarios.txt
clean_build {
    tasks = [":app:assembleDebug"]
    cleanup-tasks = ["clean"]
}
Para executar esse cenário, use o seguinte comando:
gradle-profiler --benchmark --project-dir <root-project> --scenario-file scenarios.txt
  Como usar a opção --profile do Gradle
Para gerar e ver um perfil de compilação na linha de comando do Gradle, execute as seguintes etapas:
- Abra um terminal de linha de comando na raiz do projeto.
- Execute um build limpo inserindo o seguinte comando. Ao criar perfis para
  seu build, faça um build limpo entre cada build para o qual você criar um perfil,
  porque o Gradle pula tarefas quando entradas para uma delas (como o código-fonte) não
  mudam. Dessa forma, um segundo build sem mudanças nas entradas sempre será executado mais rapidamente, porque
  as tarefas não estão sendo repetidas. Portanto, executar a tarefa cleanentre os builds garante que o perfil seja feito para todo o processo de compilação.// On Mac or Linux, run the Gradle wrapper using "./gradlew". gradlew clean 
- Execute um build de depuração de uma das suas variações de produto, como a variação “dev”,
    com as seguintes sinalizações:
gradlew --profile --offline --rerun-tasks assembleFlavorDebug - 
        --profile: ativa a criação de perfis.
- 
        --offline: impede o Gradle de buscar dependências on-line. Isso garante que qualquer atraso causado pelo Gradle ao tentar atualizar as dependências não interfira nos dados de perfil. Você precisa ter criado o projeto uma vez para garantir que o Gradle já tenha feito o download das dependências e as armazenado em cache.
- 
        --rerun-tasks: força o Gradle a executar todas as tarefas novamente e ignorar qualquer otimização de tarefas.
 
- 
        
- 
      Figura 1. Visualização do projeto indicando a localização dos relatórios de perfil. Quando a criação for concluída, use a janela Project para navegar até o diretório project-root/build/reports/profile/(conforme mostrado na Figura 1).
- 
    Com o botão direito do mouse, clique no arquivo profile-timestamp.htmle selecione Open in Browser > Default. O relatório será semelhante ao mostrado na Figura 2. Você pode inspecionar cada guia do relatório para aprender sobre seu build, como a guia Task Execution, que mostra quanto tempo o Gradle levou para executar cada tarefa de compilação.  Figura 2. Visualização de um relatório em um navegador. 
- 
    Opcional: antes de fazer qualquer alteração no projeto ou na configuração da compilação, repita o comando na etapa 3, mas omita a sinalização --rerun-tasks. Como o Gradle tenta poupar tempo evitando repetir a execução de tarefas cujas entradas não mudaram (indicadas comoUP-TO-DATEna guia Task Execution do relatório, conforme mostrado na Figura 3), você pode identificar quais tarefas estão trabalhando quando não deveriam estar. Por exemplo, se o:app:processDevUniversalDebugManifestnão estiver marcado comoUP-TO-DATE, pode ser indício de que a configuração da sua compilação atualiza o manifesto dinamicamente com cada build. Entretanto, algumas tarefas precisam ser executadas em todos os builds, como:app:checkDevDebugManifest.  Figura 3. Visualização dos resultados da execução da tarefa. 
  Agora que você tem um relatório de perfil de compilação, pode começar a buscar
  oportunidades de otimização inspecionando as informações em cada guia do
  relatório. Algumas configurações de compilação exigem experimentação, porque os benefícios podem
  variar entre projetos e estações de trabalho. Por exemplo, projetos com uma grande
  base de códigos podem se beneficiar da redução de código
  para remover códigos não utilizados e reduzir o tamanho do app. Entretanto, para projetos
  menores, talvez seja mais vantajoso desativar a redução de código. Além disso,
  aumentar o tamanho de heap do Gradle (usando
  
    org.gradle.jvmargs) pode afetar negativamente o desempenho em máquinas com pouca memória.
Após fazer uma alteração na configuração do build, observe os resultados das suas alterações repetindo as etapas acima e gerando um novo perfil de compilação. Por exemplo, a Figura 4 mostra um relatório para o mesmo exemplo de app após aplicar algumas das otimizações básicas descritas nesta página.
 
Figura 4. Visualização de um novo relatório após otimizar a velocidade de compilação.
