Perfilamento de código Go: encontrando gargalos
A otimização de desempenho é uma das principais tarefas do desenvolvedor, especialmente quando se trata de sistemas de alta carga em Go. No entanto, antes de otimizar algo, é necessário saber exatamente quais partes do código são gargalos. Para isso, existe o perfilamento — coleta e análise de métricas de execução do programa.
Neste artigo, vamos abordar como perfilar aplicações Go usando ferramentas integradas: pprof e trace. Você aprenderá a encontrar problemas relacionados a CPU, memória, bloqueios e goroutines, bem como interpretar os dados obtidos.
O que é perfilamento e por que ele é necessário?
Perfilamento é o processo de coleta de dados sobre o funcionamento de um programa durante sua execução. Esses dados ajudam a responder perguntas como:
- Quais funções consomem mais tempo de CPU?
- Onde ocorre a alocação de grandes quantidades de memória?
- Quais goroutines estão bloqueadas e em quê?
- Quanto tempo leva uma chamada de sistema ou operação de entrada/saída?
Go fornece ferramentas poderosas para perfilamento diretamente do pacote padrão. As principais são net/http/pprof para aplicações web e runtime/pprof para utilitários de linha de comando.
Ferramenta pprof: Perfis de CPU e Memória
pprof é a principal ferramenta para perfilamento em Go. Ela é capaz de coletar perfis de CPU, memória, bloqueios, goroutines e contenção de mutex.
Adicionando pprof em uma aplicação web
A maneira mais simples de habilitar o perfilamento é importar o pacote net/http/pprof:
package main
import ( "net/http" _ "net/http/pprof" // registra os handlers do pprof)
func main() { // Sua aplicação http.HandleFunc("/", handler) http.ListenAndServe(":8080", nil)}Após isso, vários perfis estarão disponíveis no endereço /debug/pprof/. Por exemplo:
/debug/pprof/profile— perfil de CPU (padrão de 30 segundos)/debug/pprof/heap— perfil de memória (heap)/debug/pprof/goroutine— dump de todas as goroutines/debug/pprof/block— perfil de bloqueios
Coleta de perfil de CPU
Para coletar o perfil de CPU, use o comando:
go tool pprof http://localhost:8080/debug/pprof/profile?seconds=30Após a coleta ser concluída, o console interativo do pprof será aberto. Os comandos mais úteis são:
top— mostra as funções que mais consomem CPUlist <função>— mostra a decomposição do tempo por linhaweb— abre o grafo de chamadas no navegador (requer Graphviz)peek <função>— mostra as funções chamadoras e chamadas
Exemplo de saída do comando top:
Showing nodes accounting for 3.50s, 70% of 5.00s total flat flat% sum% cum cum% 1.20s 24.00% 24.00% 1.20s 24.00% encoding/json.(*Decoder).Decode 0.80s 16.00% 40.00% 0.80s 16.00% runtime.mallocgc 0.60s 12.00% 52.00% 1.80s 36.00% main.processData 0.50s 10.00% 62.00% 0.50s 10.00% runtime.memmove 0.40s 8.00% 70.00% 0.40s 8.00% strings.ToLowerColeta de perfil de memória
Para analisar o uso de memória:
go tool pprof http://localhost:8080/debug/pprof/heapComandos importantes no pprof para memória:
top— funções que alocam mais memóriasample_index=alloc_space— alterna para a quantidade total de memória alocadasample_index=inuse_space— alterna para a memória atualmente em usotr