我读过sync.Pool的设计,但发现这是两个逻辑,为什么我们需要localPool来解决锁的竞争。我们可以用陈来实现一个。
使用频道比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)
}
}
}发布于 2018-06-14 07:15:50
你不是在对同一件事进行基准测试,所以你不能比较结果。
BenchmarkName()发布的goroutines具有重要的监听功能,您甚至都不需要等待这些goroutines完成,而BenchmarkNotPool()只是获取并将一个对象放在同一个goroutine的池中。
如果您修改BenchmarkName()来做同样的事情,那么基准测试的结果实际上显示了另一种方法:sync.Pool的速度是原来的3倍以上,这是事实,所以这是它的使用/优势。
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())
}
}
}结果:
BenchmarkName-8 500000 2453 ns/op
BenchmarkNotPool-8 200000 7984 ns/ophttps://stackoverflow.com/questions/50851421
复制相似问题