Maison > développement back-end > Golang > le corps du texte

Benchmark avec Golang

WBOY
Libérer: 2024-09-05 21:31:03
original
845 Les gens l'ont consulté

Bonjour les Gophers ?

Dans cet article de blog, je vais vous montrer comment utiliser un outil génial intégré au package de test #golang. Comment testeriez-vous les performances d’un morceau de code ou d’une fonction ? Utilisez des tests de référence.

Allons-y.

Pour ce test, j'utiliserai le nombre de Fibonacci classique ou la séquence de Fibonacci, qui est déterminé par :

if (x < 2) 
   F(0) = 1
   F(2) = 2
else 
   F(x) = F(x-1) + F(x-2)

In practice, the sequence is:
1, 1, 2, 3, 5, 8, 13, etc.
Copier après la connexion

Cette séquence est importante car elle apparaît également dans plusieurs parties des mathématiques et de la nature, comme indiqué ci-dessous :

Benchmark with Golang

Il existe plusieurs façons d'implémenter ce code, et j'en choisirai deux pour nos tests de référence : les méthodes récursives et itératives de calcul. L'objectif principal des fonctions est de fournir une position et de renvoyer le nombre de Fibonacci à cette position.

Méthode récursive

// main.go

func fibRecursive(n int) int {
    if n <= 2 {
        return 1
    }
    return fibRecursive(n-1) + fibRecursive(n-2)
}
Copier après la connexion

Méthode itérative

// main.go

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

    if position <= 2 {
        return 1
    }

    var result, i uint
    for i = 2; i < position; i++ {
        result = slc[i-1] + slc[i-2]
        slc[i] = result
    }

    return result
}
Copier après la connexion

Ces méthodes ne sont pas optimisées, mais les résultats des tests sont sensiblement différents même pour un petit nombre. Vous le verrez dans les tests. Pour suivre le code, vous pouvez cliquer ici.

Maintenant, pour les tests benchmark, écrivons quelques tests dans le fichier _main_test.go. En utilisant la documentation de Golang sur benchmark, vous pouvez créer les fonctions à tester comme suit :

// 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 < b.N; i++ { 
        fibIterative(uint(100))
    }
}

// Same as above
func BenchmarkFibRecursive(b *testing.B) {
    for i := 0; i < b.N; i++ {
        fibRecursive(100)
    }
}
Copier après la connexion

Question, avant de continuer : lequel est le plus rapide ?

Faisons le test pour un petit nombre (10) et pour un nombre légèrement plus grand (80). Pour exécuter les tests benchmark, il vous suffit d'exécuter la commande :

aller tester -bench=NomdelaFonction

Si vous souhaitez en savoir plus sur cette commande, cliquez ici.

Premier test : position=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
Copier après la connexion

Analysons à l'aide de cette image :

Benchmark with Golang

Selon l'image, nous avons 8 cœurs pour les tests, sans limite de temps (il fonctionnera jusqu'à la fin). Il a fallu 1,651s pour terminer la tâche.

==== 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 ====
Copier après la connexion

C’est un bon résultat. Vérifions la fonction récursive pour la position 10 :

// Results
BenchmarkFibRecursive-8          6035011               187.8 ns/op
PASS
ok      playground      1.882s
Copier après la connexion

Nous pouvons voir qu'il a fallu 1,882s pour terminer la tâche.

La fonction itérative a gagné de quelques décisecondes. Essayons encore un test avec :

Position 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
Copier après la connexion

Wow ! Maintenant, la fonction récursive est plus rapide ?

Terminons avec un nombre légèrement plus grand.

Position 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
Copier après la connexion

La différence est énorme. Pour la position 80, l'approche itérative a duré environ 2 secondes. Pour la position 50, la fonction récursive a pris environ 45 secondes. Cela démontre l'importance de comparer votre code lorsque votre projet Golang commence à ralentir.

Conclusion

Si votre code de production s'exécute lentement ou est plus lent de manière imprévisible, vous pouvez utiliser cette technique, combinée avec pprof ou d'autres outils du package de test intégré, pour identifier et tester les performances de votre code. mal et comment l'optimiser.

Remarque : tous les codes qui sont beaux à regarder ne sont pas plus performants.

Exercice supplémentaire

Pouvez-vous trouver une meilleure façon d'améliorer la fonction récursive ? (Conseil : utilisez la programmation dynamique). Cet article explique pourquoi pour certains petits nombres, la stratégie récursive est meilleure.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!