go语言基准测试通过b.ReportAllocs()可统计内存分配情况,输出包含每次操作的平均内存分配字节数(B/op)和分配次数(allocs/op),结合b.SetBytes()还能分析数据处理时的内存效率与吞吐关系。

Go语言的基准测试(Benchmark)不仅能测量代码执行时间,还能统计内存分配情况。要了解一段代码在运行时分配了多少内存、分配了多少次,可以直接通过*testing.B提供的方法获取。
使用 b.ReportAllocs() 记录内存分配
在基准测试函数中调用 b.ReportAllocs(),即可开启对内存分配的追踪。Go运行时会自动记录每次基准循环中的堆内存分配总量和分配次数。
例如:
func BenchmarkExample(b *testing.B) {
b.ReportAllocs()
for i := 0; i < b.N; i++ {
// 被测代码
_ = make([]int, 100)
}
}
运行这个基准测试时,输出结果会包含三部分:
– 基准耗时(ns/op)
– 内存分配字节数(B/op)
– 分配次数(allocs/op)
理解输出中的内存指标
执行 go test -bench=. 后,你会看到类似这样的输出:
立即学习“go语言免费学习笔记(深入)”;
BenchmarkExample-8 10000000 120 ns/op 400 B/op 1 allocs/op
其中:
- 400 B/op:表示每次操作平均分配了400字节内存
- 1 allocs/op:表示每次操作发生了1次内存分配
这些数据来自Go运行时的采样统计,仅反映堆上分配的情况,栈上分配不会计入。
结合 b.SetBytes() 测量吞吐相关的内存效率
如果你的基准测试处理的是数据流或缓冲区操作,可以配合 b.SetBytes() 来展示每秒处理的数据量与内存开销的关系。
比如测试复制1KB数据:
func Benchmarkcopy(b *testing.B) {
b.ReportAllocs()
data := make([]byte, 1024)
for i := 0; i < b.N; i++ {
copied := make([]byte, len(data))
copy(copied, data)
}
b.SetBytes(1024)
}
此时输出会额外体现带宽信息,如 MB/s,并将内存分配归一化到每字节操作的成本,帮助你判断性能瓶颈是否与内存有关。
基本上就这些。只要加上 b.ReportAllocs(),就能清楚看到你的函数在真实场景下是否频繁触发GC或产生过多小对象。这对优化性能敏感路径非常有用。


