Maison >développement back-end >Golang >Un outil d'analyse comparative de référence
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.
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) }
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) } }
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
其中,-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
计算斐波那契数列值的迭代式实现如下
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 }
对比这两种函数的性能差异,最朴素的方式就是分别对这两个函数进行基准测试,然后通过手工分析这些基准测试结果,但是这并不直观。
benchstat 是 Go 官方推荐的一款命令行工具,它用于计算和比较基准测试的相关统计数据。
我们可以通过以下命令进行安装
go install golang.org/x/perf/cmd/benchstat@latest
执行 -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")
我们想比较 FibSolution(n) 从 15 到 20,两种实现方式的性能基准测试。
$ go test -bench=. -count=5 | tee old.txt $ go test -bench=. -count=5 | tee new.txt
注意,这两条命令执行时,分别对应 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)
可以看到,递归式实现的函数,他的执行时间随着 n 值变大增加非常明显。迭代式实现方式,相较于递归式,它的平均时间开销降低了 99 % 以上,优化效果非常明显。
另外,p=0.008 表示结果的可信程度,p 值越大表明可信度越低。一般以 0.05 作为临界值,超过该值,则结果不可信。n=5+5 表示分别使用的有效样本数量。
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!