"Se um trabalhador quiser fazer bem o seu trabalho, ele deve primeiro afiar suas ferramentas." - Confúcio, "Os Analectos de Confúcio. Lu Linggong"
Primeira página > Programação > Referência com Golang

Referência com Golang

Publicado em 2024-11-04
Navegar:300

Olá, esquilos?

Nesta postagem do blog, mostrarei como usar uma ferramenta incrível integrada ao pacote de testes #golang. Como você testaria o desempenho de um trecho de código ou função? Use testes de referência.

Vamos.

Para este teste, usarei o clássico Número de Fibonacci ou Sequência de Fibonacci, que é determinado por:

if (x 



Essa sequência é importante porque aparece também em diversas partes da matemática e da natureza, conforme mostrado abaixo:

Benchmark with Golang

Existem várias maneiras de implementar esse código, e escolherei duas para nossos testes de benchmark: os métodos recursivos e iterativos de calculá-lo. O principal objetivo das funções é fornecer uma posição e retornar o número de Fibonacci nessa posição.

Método Recursivo

// main.go

func fibRecursive(n int) int {
    if n 



Método Iterativo

// main.go

func fibIterative(position uint) uint {
    slc := make([]uint, position)
    slc[0] = 1
    slc[1] = 1

    if position 



Esses métodos não são otimizados, mas os resultados dos testes são significativamente diferentes, mesmo para um pequeno número. Você verá isso nos testes. Para acompanhar o código, você pode clicar aqui.

Agora, para os testes de benchmark, vamos escrever alguns testes no arquivo _main_test.go. Usando a documentação do Golang em benchmark, você pode criar as funções a serem testadas da seguinte forma:

// main_test.go

// The key is to start every function you want to benchmark with the keyword Benchmark and use b *testing.B instead of t *testing.T as input 
func BenchmarkFibIterative(b *testing.B) {
    // Use this for-loop to ensure the code will behave correctly. 
    // Now, you can put the function or piece of code you want to test
    for i := 0; i 



Pergunta, antes de continuar: qual é mais rápido?

Vamos fazer o teste para um número pequeno (10) e para um número um pouco maior (80). Para executar os testes de benchmark, basta executar o comando:

go test -bench=NomedaFunção

Se quiser saber mais sobre este comando, confira aqui.

Primeiro teste: posição=10

//(fibIterative)
Results:
cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8         24491042                42.50 ns/op
PASS
ok      playground      1.651s

Vamos analisar com a ajuda desta imagem:

Benchmark with Golang

De acordo com a imagem, temos 8 núcleos para os testes, sem limite de tempo (será executado até a conclusão). Demorou 1.651s para concluir a tarefa.

==== Extra ====
We got 24,491,042 iterations (computations), and each iteration (op) took 42.50 ns.

Doing some math, we can calculate how much time one op took:

42.50 ns/op with 1 ns = 1/1,000,000,000 s
op ≈ 2.35270590588e-12 s
==== Extra ====

Esse é um bom resultado. Vamos verificar a função recursiva para a posição 10:

// Results
BenchmarkFibRecursive-8          6035011               187.8 ns/op
PASS
ok      playground      1.882s

Podemos ver que foram necessários 1.882s para concluir a tarefa.

A função iterativa venceu por alguns decissegundos. Vamos tentar mais um teste com:

Posição 50

// Results for the Iterative Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8         27896118                45.37 ns/op
PASS
ok      playground      2.876s

// Results for the Recursive Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibRecursive-8          6365198               186.3 ns/op
PASS
ok      playground      1.918s

Uau! Agora a função recursiva é mais rápida?

Vamos terminar com um número um pouco maior.

Posição 80

// Results for the Iterative Function

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibIterative-8          5102344               229.5 ns/op
PASS
ok      playground      1.933s

// Results for the Recursive Function
// My poor PC couldn’t handle it, so I had to reduce the position to 50 just to get some results printed.

cpu: Intel(R) Core(TM) i7-7700HQ CPU @ 2.80GHz
BenchmarkFibRecursive-8                1        44319299474 ns/op
PASS
ok      playground      44.951s

A diferença é enorme. Para a posição 80, a abordagem iterativa demorou aproximadamente 2 segundos. Para a posição 50, a função recursiva demorou cerca de 45 segundos. Isso demonstra a importância de avaliar seu código quando seu projeto Golang começa a ficar lento.

Conclusão

Se o seu código de produção estiver sendo executado lentamente ou for imprevisivelmente mais lento, você poderá usar esta técnica, combinada com pprof ou outras ferramentas do pacote de testes integrado, para identificar e testar o desempenho do seu código mal e como otimizá-lo.

Observação: nem todo código bonito aos olhos tem melhor desempenho.

Exercício Extra

Você consegue encontrar uma maneira melhor de melhorar a função recursiva? (Dica: use Programação Dinâmica). Este artigo explica por que, para alguns números pequenos, a estratégia recursiva é melhor.

Declaração de lançamento Este artigo está reproduzido em: https://dev.to/pedrobertao/benchmark-with-golang-md4?1 Caso haja alguma infração, entre em contato com [email protected] para excluí-lo
Tutorial mais recente Mais>

Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.

Copyright© 2022 湘ICP备2022001581号-3