Como fazer benchmark do seu código – Aprenda Golang
core/performance/tutoriais
func AddNomes(nomes []string, pessoas []Pessoa) []string {
index := len(nomes)
nomes = append(nomes, make([]string, len(pessoas))...)
for _, pessoa := range pessoas {
nomes[index] = pessoa.Nome
Agora, vamos escrever a função que faz o benchmark no nosso código.
func BenchmarkAddNomes(b *testing.B) {
nomes := []string{"Tiago", "Alexandre", "Luara"}
pessoas := []Pessoa{
{Nome: "Dani", Idade: 35},
{Nome: "Lucas", Idade: 29},
{Nome: "Rafael", Idade: 38},
AddNomes(nomes, pessoas)
Agora que já escrevemos nossa função de benchmark, vamos executá-lo com o comando:
Quando passamos um "." na flag -bench estamos falando para executar todas as funções de benchmark que temos. No entanto, caso a intensão seja executar somente algumas, podemos passar parte do nome das funções, como por exemplo -bench=AddNomes.
O output do comando retorna 3 colunas: NomeDaFunc-NumCPU, Num de Operações, Tempo gasto por operação.
$ BenchmarkAddNomes-4  	 3374858	       373.4 ns/op
Embora aqui já seja possível ter uma idéia de como nossa função está, podemos adicionar mais alguns parâmetros ao comando de execução.
$ go test -bench=AddNomes -cpu=8 -benchmem -benchtime=5s -count 5
Com esse novo comando estamos incrementando o número de cpu de 4 para 8, pedindo para fazer um benchmark da memória (-benchmem), por 5 segundos (-benchtime), 5 vezes (-count).
Agora temos mais 2 colunas em relação a execução anterior. Na quarta coluna temos a quantidade de Bytes por operação e na última coluna a quantidade de alocações de memória executada a cada função.
Com essas informações em mãos, você já consegue ter uma idéia se tem algo que pode ser melhorado em sua aplicação. No entanto, se você for ao post "Qual a melhor forma para aumentar um array?", verá que em baixo de cada imagem tem um total de memória, porém, como podemos ver na execução acima, em nenhum lugar aparece esse valor.
Para conseguir esse valor, precisamos adicionar uma flag para fazer o profiling da memória. Mas como esse assunto pode ser bem extenso, vou cobrir ele em outro post.
Antes de finalizar, quero ressaltar que para os valores serem precisos, temos que evitar otimizações do compilador. Para isso precisamos armazenar o resultado da função a nível do pacote.