一、单元测试与基准测试
- 单元测试
- 必须以
Test
开头 - 传递的参数类型是
*testing.T
- 使用
go test -v xxx_test.go -timeout=20m -count=1
来运行- -v打印详情测试信息
- -timeout默认10分钟超时
- -count函数运行几次
- 案例测试命令:
go test -v mytest_test.go -run=Buffer
- 必须以
func TestBuffer(t *testing.T) {
hello := "hello"
golang := "golang"
var buffer bytes.Buffer
buffer.WriteString(hello)
buffer.WriteString(",")
buffer.WriteString(golang)
fmt.Println(buffer.String()) //hello,golang
}
- 基准测试
- 必须以
Benchmark
开头 - 传递的参数类型是
*testing.B
- 使用
go test -bench=StrCat -run=^$ -benchmem -benchtime=2s -cpuprofile=data/cpu.prof -memprofile=data/mem.prof
- -bench 正则指定运行哪些基准测试
- -run 正则指定运行哪些单元测试
- -benchmem 输出内存分配情况
- -benchtime 每个函数运行多长时间
- 案例测试命令
go test -bench=StrCat -run=^$ mytest_test.go
go test -bench=StrCat -run=^$ mytest_test.go -benchmem
go test -bench=StrCat -run=^$ mytest_test.go -benchmem -benchtime=4s
go test -bench=StrCat -run=^$ mytest_test.go -benchmem -benchtime=4s -cpuprofile cpu.prof -memprofile mem.prof
- 必须以
const LOOP int = 100
func BenchmarkStrCatWithOperator(b *testing.B) {
hello := "hello"
golang := "golang"
b.ResetTimer() //重置计时器,避免上面的初始化工作带来的干扰
for i := 0; i < b.N; i++ {
var str string
for i := 0; i < LOOP; i++ { //使用“+”连接很多字符串
str += hello + "," + golang
}
}
}
func BenchmarkStrCatWithJoin(b *testing.B) {
hello := "hello"
golang := "golang"
arr := make([]string, LOOP*2)
for i := 0; i < LOOP; i++ {
arr = append(arr, hello)
arr = append(arr, golang)
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
_ = strings.Join(arr, ",")
}
}
func BenchmarkStrCatWithBuffer(b *testing.B) {
hello := "hello"
golang := "golang"
b.ResetTimer()
for i := 0; i < b.N; i++ {
var buffer bytes.Buffer
buffer.Grow(LOOP * 12) //如果能预估将来需要buffer的大小,则通过Grow()来指定,以获得最佳性能。这一行不是必须的
for i := 0; i < LOOP; i++ {
buffer.WriteString(hello)
buffer.WriteString(",")
buffer.WriteString(golang)
}
_ = buffer.String()
}
}
- 测试代码规范
- 单元测试和基准测试必须放在以_test.go为后缀的文件里
- 单元测试函数以Test开头,基准测试函数以Benchmark开头
- 单元测试以*testing.T为参数,函数无返回值
- 基准测试以*testing.B为参数,函数无返回值
二、proof
- proof是可视化的性能分析工具:
- CPU Profiling:按一定频率采集CPU使用情况
- Memory Profiling:监控内存使用情况,检查内存泄漏
- Goroutine Profiling:对正在运行的Goroutine进行堆栈跟踪和分析,检查协程泄漏
- 监控CPU:使用命令
go tool pprof cpu.prof
,进入交互界面(cpu.prof就是使用基准测试-cpuprofile cpu.prof
生成出来的)- topn:列出最耗计算资源的前n个函数
- list func:列出某函数里每一行代码消耗多少计算资源
- peek func:列出某函数里最耗计算资源的前几个子函数
-
安装Graphviz:https://www.graphviz.org/download/,选择自己对应的版本下载安装即可
-
查看是否安装成功:
dot -v
-
需要在用户的path中添加Graphviz的bin目录:
-
可视化查看pprof的结果:用户path路径配置完需要重启下ide,才可以生效
go tool pprof -http=:8080 cpu.prof
-
内存情况查看也是同理:
go tool pprof -http=:8080 cpu.prof