Go sync.Pool Slice Benchmark

纠结于[]struct还是[]*struct
直接make([]struct,0) 后append 还是 用sync.Pool make([]struct,100)

写段代码跑个分, 结论是

  1. []*struct的要比[]struct多n次取指针的内存分配, 所有更慢, 如果不用修改结构体元素内的值, 没有必要用指针切片
  2. append[]*struct要比[]struct
  3. sync.Pool效果明显

benchmark结果

BenchmarkStructSliceWithoutPool-8 200000 5458 ns/op 16320 B/op 8 allocs/op
BenchmarkStructPointerSliceWithoutPool-8 200000 6045 ns/op 8504 B/op 109 allocs/op
BenchmarkStructSliceWithPool-8 1000000 1287 ns/op 32 B/op 1 allocs/op
BenchmarkStructPointerSliceWithPool-8 300000 4910 ns/op 6498 B/op 102 allocs/op

benchmark代码

package main
import (
"sync"
"testing"
)
var structSlicePool = sync.Pool{
New: func() interface{} {
return make([]Basic, 100)
},
}
var structPointerSlicePool = sync.Pool{
New: func() interface{} {
return make([]*Basic, 100)
},
}
type Basic struct {
Id, N1, N2, N3, N4, N5 int
Name string
}
func BenchmarkStructSliceWithoutPool(b *testing.B) {
for i := 0; i < b.N; i++ {
var list []Basic
for j := 0; j < 101; j++ {
var data = Basic{Id: j, Name: "Name"}
list = append(list, data)
}
}
}
func BenchmarkStructPointerSliceWithoutPool(b *testing.B) {
for i := 0; i < b.N; i++ {
var list []*Basic
for j := 0; j < 101; j++ {
var data = Basic{Id: j, Name: "Name"}
list = append(list, &data)
}
}
}
func BenchmarkStructSliceWithPool(b *testing.B) {
for i := 0; i < b.N; i++ {
list := structSlicePool.Get().([]Basic)
initLen := len(list)
for j := 0; j < 101; j++ {
var data = Basic{Id: j, Name: "Name"}
if j < initLen {
list[j] = data
} else {
list = append(list, data)
}
}
structSlicePool.Put(list)
}
}
func BenchmarkStructPointerSliceWithPool(b *testing.B) {
for i := 0; i < b.N; i++ {
list := structPointerSlicePool.Get().([]*Basic)
initLen := len(list)
for j := 0; j < 101; j++ {
var data = Basic{Id: j, Name: "Name"}
if j < initLen {
list[j] = &data
} else {
list = append(list, &data)
}
}
structPointerSlicePool.Put(list)
}
}
分享到 评论