Go语言通过testing包的Benchmark函数测量性能,需定义以Benchmark开头、参数为*testing.B的函数;2. 示例中测试字符串拼接函数性能,使用b.ResetTimer重置计时,循环执行i次以评估每操作耗时。

在Go语言开发中,性能优化离不开可靠的测试手段。Go内置的
testing
Benchmark函数写在
_test.go
Benchmark
*testing.B
假设有一个字符串拼接函数:
func ConcatStrings(strs []string) string {
var result string
for _, s := range strs {
result += s
}
return result
}
对应的benchmark测试如下:
立即学习“go语言免费学习笔记(深入)”;
func BenchmarkConcatStrings(b *testing.B) {
strs := []string{"a", "b", "c", "d", "e"}
b.ResetTimer()
for i := 0; i < b.N; i++ {
ConcatStrings(strs)
}
}
b.N是系统自动设定的迭代次数,Go会不断调整它,直到获得稳定的统计结果。
通过编写多个benchmark函数,可以横向比较不同算法或实现的性能差异。
比如用
strings.Join
func JoinStrings(strs []string) string {
return strings.Join(strs, "")
}
添加对应的benchmark:
func BenchmarkJoinStrings(b *testing.B) {
strs := []string{"a", "b", "c", "d", "e"}
b.ResetTimer()
for i := 0; i < b.N; i++ {
JoinStrings(strs)
}
}
运行命令:
go test -bench=.
输出类似:
BenchmarkConcatStrings-8 10000000 150 ns/op BenchmarkJoinStrings-8 20000000 80 ns/op
可见
strings.Join
为了模拟真实场景,可以在benchmark中动态调整输入大小。
例如测试不同长度切片的表现:
func BenchmarkConcatStrings_10(b *testing.B) { benchConcat(b, 10) }
func BenchmarkConcatStrings_100(b *testing.B) { benchConcat(b, 100) }
func benchConcat(b *testing.B, size int) {
strs := make([]string, size)
for i := range strs {
strs[i] = "x"
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
ConcatStrings(strs)
}
}
另外,如果函数返回值未被使用,编译器可能直接优化掉调用。可通过
b.ReportMetric
blackhole
var result string result = ConcatStrings(strs)
或使用
runtime.GC
b.Run("WithGC", func(b *testing.B) {
for i := 0; i < b.N; i++ {
ConcatStrings(strs)
if i%100 == 0 {
runtime.GC()
}
}
})
加上
-benchmem
go test -bench=. -benchmem
输出中包含:
理想情况下应尽量减少这两项数值。例如,使用
strings.Builder
func BuildString(strs []string) string {
var sb strings.Builder
for _, s := range strs {
sb.WriteString(s)
}
return sb.String()
}
其benchmark通常会显示更低的内存分配和更高的吞吐量。
基本上就这些。掌握benchmark写法后,可以持续监控关键函数的性能变化,尤其在重构或升级依赖时非常有用。
以上就是Golang使用benchmark测试性能实践的详细内容,更多请关注php中文网其它相关文章!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号