gpt4 book ai didi

go - sync.Pool 比使用 channel 慢很多,为什么要使用 sync.Pool?

转载 作者:IT王子 更新时间:2023-10-29 01:52:02 27 4
gpt4 key购买 nike

看了sync.Pool的设计,发现是两个逻辑,为什么要用localPool来解决锁竞争。我们可以只使用 chan 来实现一个。

使用 channel 比 sync.pool 快 4 倍!

pool除了可以clear object,还有什么优势呢?

这是池实现和基准测试代码:

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)
}
}
}

最佳答案

您没有对同一事物进行基准测试,因此无法比较结果。

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/op

另见相关问题:How to implement Memory Pooling in Golang

关于go - sync.Pool 比使用 channel 慢很多,为什么要使用 sync.Pool?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50851421/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com