Introdução: por que a profilaxia do código Kotlin é criticamente importante
Ao desenvolver em Kotlin — uma linguagem moderna, concisa e segura para JVM, Android e projetos multiplataforma — o desempenho muitas vezes fica em segundo plano. Escrevemos código limpo, usamos corrotinas, delegados e extensões, mas um dia o aplicativo começa a travar: animações congelam, requisições de API demoram mais do que o esperado e a memória cresce como fermento. Nesses casos, a intuição e a revisão de código não ajudam — é necessária uma abordagem científica.
Profilaxia é o processo de medir o tempo de execução, o uso de memória, a carga da CPU e outras métricas para identificar gargalos. Sem ela, você corre o risco de otimizar as partes erradas, gastando horas em micro-otimizações inúteis. Neste artigo, vamos abordar como fazer profiling de código Kotlin, quais ferramentas usar e como interpretar os resultados. O material será útil para desenvolvedores Android, engenheiros backend com Ktor e todos que escrevem em Kotlin para JVM.
Métricas principais e ferramentas de profiling
Antes de nos aprofundarmos no código, é importante entender o que exatamente estamos medindo. As principais métricas de profiling são:
- Tempo de execução (CPU Time) — quanto tempo de processador um método ou bloco de código consumiu.
- Wall Clock Time — o tempo real do início ao fim da execução, incluindo espera de entrada/saída.
- Uso de memória (Heap Memory) — a quantidade de objetos criados no heap e o tempo de coleta de lixo (GC).
- Número de alocações — quantas vezes um novo objeto foi criado. Muitas vezes é um assassino oculto do desempenho.
Para Kotlin na JVM, as seguintes ferramentas estão disponíveis:
- IntelliJ Profiler (Async Profiler) — profiler integrado ao IntelliJ IDEA Ultimate para CPU e memória. Suporta sampling (amostragem) e tracing (rastreamento).
- JProfiler — ferramenta comercial poderosa com visualização de threads, heap e GC.
- VisualVM — profiler gratuito que faz parte do JDK. Permite monitorar um aplicativo em execução.
- YourKit — outro profiler comercial com excelente suporte para Kotlin e corrotinas.
- Android Studio Profiler — para aplicativos Android: CPU, Memory, Network e Energy.
Para microbenchmarking (medição de desempenho de funções individuais), use kotlinx-benchmark — uma biblioteca baseada em JMH (Java Microbenchmark Harness).
Exemplo prático: profiling de CPU e memória
Passo 1: Preparação do código para profiling
Suponha que temos uma função que processa uma lista de usuários e gera um relatório. Suspeitamos que ela está lenta. Aqui está o código original:
data class User(val id: Int, val name: String, val email: String)
fun generateReport(users: List<User>): String { val sb = StringBuilder() for (user in users) { sb.append("ID: ${user.id}, Name: ${user.name}, Email: ${user.email}") } // Processamento adicional: filtragem e ordenação val filtered = users.filter { it.email.contains("@") } .sortedBy { it.name } for (u in filtered) { sb.append("Filtered: ${u.name}") } return sb.toString()}Parece inofensivo, mas com uma lista de 100.000 elementos, isso pode se tornar um problema.
Passo 2: Executando profiling de CPU no IntelliJ IDEA
Abra o IntelliJ IDEA Ultimate, execute o aplicativo e selecione Run → Profile 'main' (ou use o ícone de profiling ao lado do botão Run). O IntelliJ iniciará o Async Profiler e mostrará um Flame Graph (gráfico de chamas).
Após a conclusão do profiling, você verá algo como:
CPU profiling result:- generateReport: 85% do tempo - String conc