使用Benchmark函数可评估Go代码性能,通过testing.B参数实现自动循环测试,结合b.Run和b.ResetTimer精确测量不同输入规模下的执行时间与内存分配,分析算法复杂度并优化代码。

在Go语言中,使用Benchmark函数可以评估代码在不同输入规模下的性能表现。通过testing包提供的基准测试机制,你可以模拟从小到大的数据量,观察函数的执行时间、内存分配等指标,从而分析其时间复杂度和优化空间。
编写基础Benchmark函数
基准测试函数以Benchmark开头,接收*testing.B参数。测试会自动循环执行目标代码多次,直到获得稳定的性能数据。
func BenchmarkSort(b *testing.B) {
data := make([]int, 1000)
for i := 0; i < b.N; i++ {
sort.Ints(data)
}
}
其中b.N由测试框架动态调整,确保测试运行足够长时间以获取准确结果。
立即学习“go语言免费学习笔记(深入)”;
测试多个输入规模
为了观察性能随输入变化的趋势,可以在同一个基准函数中遍历不同的数据规模。
示例:测试不同长度切片的排序性能func BenchmarkSortDifferentSizes(b *testing.B) {
sizes := []int{10, 100, 1000, 10000}
for _, n := range sizes {
b.Run(fmt.Sprintf("Size_%d", n), func(b *testing.B) {
data := make([]int, n)
for i := range data {
data[i] = rand.Intn(1000)
}
for i := 0; i < b.N; i++ {
sort.Ints(append([]int(nil), data...)) // 避免原地修改影响后续迭代
}
})
}
}
关键点:
Python v2.4版chm格式的中文手册,内容丰富全面,不但是一本手册,你完全可以把她作为一本Python的入门教程,教你如何使用Python解释器、流程控制、数据结构、模板、输入和输出、错误和异常、类和标准库详解等方面的知识技巧。同时后附的手册可以方便你的查询。
- 使用
b.Run为每个规模创建子测试,输出更清晰 - 每次复制数据避免排序副作用
- 初始化数据应在
b.N循环外,仅测量核心操作
控制变量与准确测量
确保只测量目标操作,避免将数据准备时间计入性能结果。
func BenchmarkSearch(b *testing.B) {
for _, size := range []int{1e3, 1e4, 1e5} {
b.Run(fmt.Sprintf("BinarySearch_%d", size), func(b *testing.B) {
slice := make([]int, size)
for i := range slice {
slice[i] = i * 2
}
b.ResetTimer() // 开始计时前重置
for i := 0; i < b.N; i++ {
binarySearch(slice, size*2)
}
})
}
}
技巧:
- 用
b.ResetTimer()排除预处理开销 - 若函数返回值可能被编译器优化掉,可用
blackhole = result或benchmem标记查看内存分配 - 使用
-benchmem参数运行测试可显示每次操作的内存分配次数和字节数
运行与分析结果
执行命令:go test -bench=BenchmarkSortDifferentSizes -benchmem
输出示例:
BenchmarkSortDifferentSizes/Size_10
10000000 15.2 ns/op 0 B/op 0 allocs/op
BenchmarkSortDifferentSizes/Size_1000
100000 2100 ns/op 8000 B/op 1 allocs/op
观察ns/op增长趋势可判断算法是否符合预期(如O(n log n)),结合内存分配情况优化实现。
基本上就这些,关键是构造合理的输入规模梯度,并确保测量纯净。









