我读过sync.Pool
设计,但发现它是两个逻辑,为什么我们需要localPool来解决锁定竞争。我们可以使用chan实现一个。
使用频道比sync.pool
快4倍!
除了游泳池可以清除对象,它有什么优势?
这是池实现和基准测试代码:
package client
import (
"runtime"
"sync"
"testing"
)
type MPool chan interface{}
type A struct {
s string
b int
overflow *[2]*[]*string
}
var p = sync.Pool{
New: func() interface{} { return new(A) },
}
var mp MPool = make(chan interface{}, 100)
func get() interface{} {
select {
case r := <-mp:
return r
default:
return new(A)
}
}
func put(a interface{}) {
select {
case mp <- a:
default:
}
return
}
func pool() {
a := p.Get()
p.Put(a)
}
func init() {
runtime.GOMAXPROCS(8)
}
func BenchmarkName(b *testing.B) {
for i := 0; i < 20; i++ {
p.Put(new(A))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for i := 0; i < 100; i++ {
go func() {
p.Put(p.Get())
}()
}
}
}
func BenchmarkNotPool(b *testing.B) {
for i := 0; i < 20; i++ {
put(new(A))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for i := 0; i < 100; i++ {
a := get()
put(a)
}
}
}
答案 0 :(得分:4)
您没有对相同的事情进行基准测试,因此您无法比较结果。
if (e.deltaY>0) {
owl.trigger('next.owl', [5000]);
} else {
owl.trigger('prev.owl', [5000]);
}
启动goroutines,这些goroutine有重要的被无意中听到,你甚至不等待那些goroutine完成,而BenchmarkName()
只是获取并将一个对象放入池中的同一个goroutine。
如果你修改BenchmarkNotPool()
来做同样的事情,那么基准测试结果实际上表明它是另一种方式:BenchmarkName()
快3倍以上,这是真的,所以这是它的使用/优势。 / p>
sync.Pool
结果:
func BenchmarkName(b *testing.B) {
for i := 0; i < 20; i++ {
p.Put(new(A))
}
b.ResetTimer()
for i := 0; i < b.N; i++ {
for i := 0; i < 100; i++ {
p.Put(p.Get())
}
}
}