Benchmark Retornos Nomeados vs Explicitos em Go

Surgiu uma dúvida no grupo de estudos de Go sobre a diferença de velocidade entre tipos de retorno. A hipótese é que retornos nomeados são mais rápidos que retornos explícitos.

Felizmente, Go possui um bom conjunto de ferramentas, e podemos verificar essa hipótese.

Vamos começar criando um código com duas funções de soma: uma com retornos nomeados e outra com retornos explícitos.

package main

import (
	"testing"
)

// Função com retornos nomeados
func somaNomeados(a, b int) (resultado int, err error) {
	resultado = a + b
	return
}

// Função com retornos explícitos
func somaExplicitos(a, b int) (int, error) {
	return a + b, nil
}

Em seguida, criamos as funções de benchmark. O nome dessas funções é importante, pois a ferramenta de testes do Go procura funções que comecem com a palavra Benchmark.

func BenchmarkSomaNomeados(b *testing.B) {
	for i := 0; i < b.N; i++ {
		somaNomeados(1, 2)
	}
}

func BenchmarkSomaExplicitos(b *testing.B) {
	for i := 0; i < b.N; i++ {
		somaExplicitos(1, 2)
	}
}

Veja o código completo

Nomeie o arquivo como benchmark_retornos_test.go. Além do nome das funções, o nome do arquivo é importante. Ele deve terminar com _test.go para que o Go encontre os testes.

Para rodar o benchmark, execute o seguinte comando:

go test -bench=.

No meu caso, o resultado foi este:

goos: darwin
goarch: arm64
pkg: benchmarkRetorno
cpu: Apple M2
BenchmarkSomaNomeados-8     	1000000000	         0.2926 ns/op
BenchmarkSomaExplicitos-8   	1000000000	         0.2879 ns/op
PASS
ok  	benchmarkRetorno	1.167s

Para minha surpresa, os retornos explícitos foram ligeiramente mais rápidos em vários testes. Contudo, isso é provavelmente uma anomalia do teste causada pela instrumentação do Go. Diferenças de sub-nanosegundos podem ser ignoradas.

Quando compilado com go build, o código binário gerado pelas duas funções é idêntico.

Para concluir, retornos nomeados e explícitos têm o mesmo desempenho. A escolha entre eles deve ser feita com base na legibilidade do código.

Cesar Gimenes

Última modificação