Open geektutu opened 3 years ago
3.2 bytes.Buffer
①看到 BenchmarkBuffer
测试方法没有添加 buf.Reset()
方法,测试加上效果还是 pool 的性能更好
func BenchmarkBuffer(b *testing.B) {
for n := 0; n < b.N; n++ {
var buf bytes.Buffer
buf.Write(data)
}
}
②特意测试了:如果都不使用 Reset buf 操作,反而 pool 的性能不如原始的了!
func BenchmarkBufferWithPool(b *testing.B) {
for n := 0; n < b.N; n++ {
buf := bufferPool.Get().(*bytes.Buffer)
buf.Write(data)
// buf.Reset()
bufferPool.Put(buf)
}
}
@lisgroup 第一个问题,buf 每次都是新申请的,所以没有必要 Reset()
第二个问题,buf.Reset()
相当于时执行了 buf.Truncate(0)
,把 slice 的大小设置为 0,底层的 byte 数组没有释放,所以加上 buf.Reset()
时不会影响性能的。这里 buf.Reset()
是必须执行的,如果不执行,下次从 pool 中取出来再用时,就是在原来的 buf 上追加写了,会导致错误的结果。
我这里跑的 BenchmarkUnmarshal
和文中差距有点大, go version go1.16.6 darwin/amd64
:
goos: darwin
goarch: amd64
pkg: bench
cpu: Intel(R) Core(TM) i7-1068NG7 CPU @ 2.30GHz
BenchmarkUnmarshalWithoutPool-8 1596366 742.6 ns/op 240 B/op 6 allocs/op
BenchmarkUnmarshalWithPool-8 1000000000 0.0000072 ns/op 0 B/op 0 allocs/op
这测试不是特别准确,pool的测试相当于在外部定义了个变量,然后一直用这一个变量,所以pool的测试应该用并发测试看节省的内存
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkUnmarshal-12 12528 95266 ns/op 1400 B/op 8 allocs/op
BenchmarkUnmarshalWithPool-12 12388 94105 ns/op 1423 B/op 8 allocs/op
同样的代码,性能并没有太大差别 go version go1.17 darwin/amd64
https://geektutu.com/post/hpg-sync-pool.html
Go 语言/golang 高性能编程,Go 语言进阶教程,Go 语言高性能编程(high performance go)。Go 语言标准库中的 sync.Pool 可以建立对象池,复用已有对象,解决内存分配碎片化的问题,有效减轻垃圾回收的压力(Garbage Collection, GC),在特定场景下可以有效地降低内存占用,提升性能。最后介绍了 sync.Pool 的作用和用法。