基准测试

Go语言标准库内置的 testing 测试框架提供了基准测试(benchmark)的能力,实现了对某个特定目标场景的某项性能指标进行定量的和可对比的测试。

基本规则

  1. 基准测试的代码文件必须以_test.go结尾
  2. 基准测试的函数必须以Benchmark开头,必须是可导出的
  3. 基准测试函数必须接受一个指向Benchmark类型的指针作为唯一参数
  4. b.ResetTimer是重置计时器,这样可以避免for循环之前的初始化代码的干扰
  5. 最后的for循环很重要,被测试的代码要放到循环里
  6. b.N是基准测试框架提供的,表示循环的次数,因为需要反复调用测试的代码,才可以评估性能

常用命令

$ go test -bench=. -benchmem
  1. 使用 -bench=. 标记,它接受一个表达式作为参数,匹配基准测试的函数,. 表示运行所有基准测试。
  2. 使用 -benchmem 提供每次操作分配内存的次数,以及每次操作分配的字节数。
  3. 使用 -run=none 匹配单元测试方法,这里使用 none 是因为没有这个名字的单元测试方法,等效于过滤掉单元测试的输出。
  4. 使用 -benchtime=3s 指定测试的时间,例如3秒,测试时间默认是1秒。
  5. 使用 -count=3 用来设置 benchmark 的轮数。例如,进行3轮benchmark。

举个栗子

评估1000个字符串的连接性能,分别使用 + 操作符、bytes.Bufferstrings.Builder 进行测试。

package main

import (
"bytes"
"strings"
"testing"
) var strLen = 1000 func BenchmarkConcatString(b *testing.B) {
var str string
i := 0
b.ResetTimer()
for n := 0; n < b.N; n++ {
str += "x" i++
if i >= strLen {
i = 0
str = ""
}
}
} func BenchmarkConcatBuffer(b *testing.B) {
var buffer bytes.Buffer i := 0 b.ResetTimer()
for n := 0; n < b.N; n++ {
buffer.WriteString("x") i++
if i >= strLen {
i = 0
buffer = bytes.Buffer{}
}
}
}

在终端运行命令 go test -bench=. -benchmem,输入如下信息:

$ go test -bench=^BenchmarkConcat -benchmem
goos: darwin
goarch: amd64
pkg: go_learning_notes/benchmark
cpu: Intel(R) Core(TM) i5-7360U CPU @ 2.30GHz
BenchmarkConcatString-4 8040235 140.5 ns/op 530 B/op 0 allocs/op
BenchmarkConcatBuffer-4 168521010 6.384 ns/op 2 B/op 0 allocs/op
BenchmarkConcatBuilder-4 464368256 2.475 ns/op 2 B/op 0 allocs/op
PASS
ok go_learning_notes/benchmark 5.035s

通过上面的指标信息,可以得出结论 bytes.Bufferstrings.Builder+ 操作符 更快。

参考文章

  1. Practical Go Benchmarks:https://www.instana.com/blog/practical-golang-benchmarks/
  2. Benchmarks of Go serialization methods:https://github.com/alecthomas/go_serialization_benchmarks
  3. Debugging performance issues in Go programs:https://github.com/golang/go/wiki/Performance

最新文章

  1. Triangle - Delaunay Triangulator
  2. jquery easyui使用(四)&#183;&#183;&#183;&#183;&#183;&#183;添加,编辑,删除
  3. Unity3D 5.x 简单实例 - 发射炮弹
  4. 【Swift学习】Swift编程之旅---枚举(十二)
  5. Sharepoint 2010 工作流启动时处理表单出错
  6. 主机和虚拟机能相互ping通但是不能复制
  7. C++ string 类的 find 方法实例详解
  8. win7如何配置access数据源
  9. Gensim进阶教程:训练word2vec与doc2vec模型
  10. jQuery中 wrap() wrapAll() 与 wrapInner()的区别
  11. (转)SQLSERVER表分区的介绍(一)
  12. Annotation【转】
  13. 为网站添加一个图标icon
  14. JAVA之序列化A
  15. MDK下调试时提示AXF文件无法导入的解决方法(转)
  16. 庞玉栋:浅谈seo优化对于网站建设的重要性
  17. AWS-SS配置过程
  18. (7)udp-socket
  19. 常用的js代码合集
  20. NLP入门(三)词形还原(Lemmatization)

热门文章

  1. 实体转为json的,如何处理外键情况
  2. velocity使用foreach进行遍历时$velocityCount不起作用
  3. win10修改Docker Desktop Installer的默认安装目录
  4. centos7使用Dockerfile(docker-compose)运行jar包
  5. Oracle根据约束条件名称查找对应的数据
  6. JAVA使用LocalDate获取当前日期所在季度的开始日期和结束日期
  7. vc mfc listctrl使用虚拟列表 虚拟列表用法
  8. 【LeetCode】66. Plus One 解题报告(Python)
  9. 【LeetCode】275. H-Index II 解题报告(Python)
  10. 【LeetCode】822. Card Flipping Game 解题报告(Python)