Maison > développement back-end > Golang > Un outil d'analyse comparative de référence

Un outil d'analyse comparative de référence

Libérer: 2023-07-21 13:11:05
avant
1100 Les gens l'ont consulté
Dans Go, vous pouvez facilement effectuer des tests de performances sur un certain point de fonction en écrivant une fonction Benchmark. Pour les fonctions importantes, nous pouvons ajouter des processus de test correspondants dans CI/CD pour détecter les changements dans les performances des fonctions en temps opportun. Se pose alors la question : comment détecter les changements de performances de la fonction ?

En d'autres termes, vous avez écrit une certaine fonction mais avez constaté qu'elle s'exécute très lentement et vous devez optimiser la fonction lorsque vous effectuez une recherche sur Google pour trouver une meilleure implémentation, vous constatez qu'elle est effectivement devenue plus rapide. via la fonction Benchmark. Mais vous ne pouvez pas dire à quel point il est devenu plus rapide. Vous voulez connaître la comparaison des performances avant et après l'optimisation des fonctions, de combien de points de pourcentage elle s'est améliorée et est-elle très fiable ?

Pour les scénarios de demande ci-dessus, il existe un outil qui peut vous aider, c'est benchstat.

Exemple de référence

Examinons d'abord le benchmark. Pour faciliter la compréhension, nous prenons ici comme exemple le calcul classique des valeurs de séquence de Fibonacci.

func FibSolution(n int) int {
 if n < 2 {
  return n
 }

 return FibSolution(n-1) + FibSolution(n-2)
}
Copier après la connexion

Le code ci-dessus est une implémentation récursive. Évidemment, lorsque n devient de plus en plus grand, le fonctionnement de cette fonction deviendra très long. En prenant n comme exemple 20, la fonction Benchmark est la suivante

func BenchmarkFib20(b *testing.B) {
 for i := 0; i < b.N; i++ {
  FibSolution(20)
 }
}
Copier après la connexion

Exécution de la ligne de commande<code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;background: rgba(14, 210, 247, 0.15);"><span style="font-size: 15px;">go test -bench=BenchmarkFib20</span>go test -bench=BenchmarkFib20Obtenez des résultats de performances

🎜
BenchmarkFib20-8           39452             30229 ns/op
Copier après la connexion

其中,-8 代表的是 8 cpu,函数运行次数为 39452,每次函数的平均花费时间为 30229ns。如果我们想得到多次样本数据,可以指定 go test 的 <span style="font-size: 15px;">-count=N</span> 参数。例如想得到 5 次样本数据,则执行<span style="font-size: 15px;">go test -bench=BenchmarkFib20 -count=5</span>

BenchmarkFib20-8           39325             30297 ns/op
BenchmarkFib20-8           39216             30349 ns/op
BenchmarkFib20-8           39901             30251 ns/op
BenchmarkFib20-8           39336             30455 ns/op
BenchmarkFib20-8           39423             30894 ns/op
Copier après la connexion

计算斐波那契数列值的迭代式实现如下

func FibSolution(n int) int {
 if n < 2 {
  return n
 }
 p, q, r := 0, 0, 1
 for i := 2; i <= n; i++ {
  p = q
  q = r
  r = p + q
 }
 return r
}
Copier après la connexion

对比这两种函数的性能差异,最朴素的方式就是分别对这两个函数进行基准测试,然后通过手工分析这些基准测试结果,但是这并不直观。

benchstat

benchstat 是 Go 官方推荐的一款命令行工具,它用于计算和比较基准测试的相关统计数据。

我们可以通过以下命令进行安装

go install golang.org/x/perf/cmd/benchstat@latest
Copier après la connexion

执行 -h 参数可以看到该工具的使用描述

~ $ benchstat -h
usage: benchstat [options] old.txt [new.txt] [more.txt ...]
options:
  -alpha α
     consider change significant if p < α (default 0.05)
  -csv
     print results in CSV form
  -delta-test test
     significance test to apply to delta: utest, ttest, or none (default "utest")
  -geomean
     print the geometric mean of each file
  -html
     print results as an HTML table
  -norange
     suppress range columns (CSV only)
  -sort order
     sort by order: [-]delta, [-]name, none (default "none")
  -split labels
     split benchmarks by labels (default "pkg,goos,goarch")
Copier après la connexion

我们想比较 FibSolution(n) 从 15 到 20,两种实现方式的性能基准测试。

$ go test -bench=. -count=5 | tee old.txt
$ go test -bench=. -count=5 | tee new.txt
Copier après la connexion

注意,这两条命令执行时,分别对应 FibSolution 函数采用递归式和迭代式实现逻辑。

此时,我们可以对这两个函数实现逻辑进行性能对比

 $ benchstat old.txt new.txt 
name     old time/op  new time/op  delta
Fib15-8  2.67µs ± 2%  0.01µs ± 5%  -99.81%  (p=0.008 n=5+5)
Fib16-8  4.20µs ± 1%  0.01µs ± 2%  -99.87%  (p=0.008 n=5+5)
Fib17-8  6.81µs ± 0%  0.01µs ± 2%  -99.92%  (p=0.008 n=5+5)
Fib18-8  11.1µs ± 1%   0.0µs ± 1%  -99.95%  (p=0.008 n=5+5)
Fib19-8  18.0µs ± 2%   0.0µs ± 4%  -99.97%  (p=0.008 n=5+5)
Fib20-8  29.2µs ± 1%   0.0µs ± 3%  -99.98%  (p=0.008 n=5+5)
Copier après la connexion

可以看到,递归式实现的函数,他的执行时间随着 n 值变大增加非常明显。迭代式实现方式,相较于递归式,它的平均时间开销降低了 99 % 以上,优化效果非常明显。

另外,p=0.008 表示结果的可信程度,p 值越大表明可信度越低。一般以 0.05 作为临界值,超过该值,则结果不可信。n=5+5 表示分别使用的有效样本数量。

Résumé

benchstat est un outil statistique de référence qui peut être utilisé pour réduire le coût de l'analyse manuelle des données lorsque nous effectuons des travaux d'optimisation.

Si votre projet déploie des tests automatisés dans le processus CI/CD, vous souhaiterez peut-être ajouter cet outil. Lorsque des modifications sont apportées à des fonctions qui augmentent la perte de performances, cela peut vous aider à détecter les problèmes à l'avance.


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!

Étiquettes associées:
source:Go语言进阶学习
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