不要反复从固定字符串创建字节 slice,因为重复的切片初始化会带来性能损耗。相反,请执行一次转换并捕获结果。
func BenchmarkStringToByte(b *testing.B) {
for i := 0; i < b.N; i++ {
by := []byte("Hello world")
_ = by
}
}
func BenchmarkStringToByteOnce(b *testing.B) {
bys := []byte("Hello world")
for i := 0; i < b.N; i++ {
by := bys
_ = by
}
}
看一下性能差异,注意需要禁止编译器优化,不然看不出差别。
go test -bench=BenchmarkStringToByte -gcflags="-N" main/perf
goos: windows
goarch: amd64
pkg: main/perf
cpu: Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
BenchmarkStringToByte-8 748467979 1.582 ns/op
BenchmarkStringToByteOnce-8 878246492 1.379 ns/op
PASS
ok main/perf 2.962s
差距不是很大,但是随着字符串长度的增加,差距将会越来越明显。此外,如果这种重复的转换在 Hot Path 上,那么其对性能的影响将被放大。这里解释下 Hot Path,即热点路径,顾名思义,是你的程序中那些会频繁执行到的代码。