Golang Go语言中为啥用了 sync.pool,反而会慢很多
Golang Go语言中为啥用了 sync.pool,反而会慢很多
代码如下,用了 sync.pool 反而慢,为啥呢?
结果:withoutpool 0s
with pool 23 秒
package main
import ( "fmt" "sync" "time" )
// 一个[]byte 的对象池,每个对象为一个[]byte var bytePool = sync.Pool{ New: func() interface{} { b := make([]byte, 1024) return &b }, }
func main() { a := time.Now().Unix() // 不使用对象池 for i := 0; i < 1000000000; i++{ obj := make([]byte,1024) _ = obj } b := time.Now().Unix() // 使用对象池 for i := 0; i < 1000000000; i++{ obj := bytePool.Get().(*[]byte) _ = obj bytePool.Put(obj) } c := time.Now().Unix() fmt.Println("without pool ", b - a, "s") fmt.Println("with pool ", c - b, "s") }
更多关于Golang Go语言中为啥用了 sync.pool,反而会慢很多的实战教程也可以访问 https://www.itying.com/category-94-b0.html
最起码把代码用 markdown 格式 排版一下吧,这一大坨谁能看得懂你在描述什么
更多关于Golang Go语言中为啥用了 sync.pool,反而会慢很多的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
put get 都有锁,同样的情况每次都加锁你想能快?我想你大概没理解 pool 的用法
另外:
最起码把代码用 markdown 格式 排版一下吧,这一大坨谁能看得懂你在描述什么
单一线程,生命期短,这种对象用 sync.Pool 没有意义
在第一次循环结束后调用 runtime.GC()
再进行比较
这不是搞笑吗,不用对象池的那个循环,一到下一循环上次创建的数据就没人引用了,编译器直接优化了,不管你是循环一百亿次,内存占用几乎等于 0,当然秒完
在Go语言中,sync.Pool
是一个用于临时对象缓存的池子,旨在减少GC(垃圾回收)的压力和提升性能,特别是在频繁分配和释放相同类型对象的场景下。然而,使用 sync.Pool
后发现程序变慢的情况,可能有以下几个原因:
-
对象生命周期不匹配:如果对象在池中存活时间过长,可能会导致内存占用增加,反而影响性能。
sync.Pool
适用于短生命周期对象的复用,若对象生命周期较长,则复用效果有限。 -
锁竞争:在高并发场景下,
sync.Pool
的内部实现涉及锁操作,可能导致性能瓶颈。虽然Go的锁实现相对高效,但在极高并发下仍可能成为性能瓶颈。 -
池大小配置不当:
sync.Pool
没有提供直接设置池大小的接口,其内部通过复杂的算法来管理对象。如果对象数量远超过池的管理能力,可能会导致频繁的GC,反而降低性能。 -
GC压力:虽然
sync.Pool
旨在减少GC压力,但在某些情况下,由于池的使用方式不当,可能导致对象频繁进出池,反而增加GC的复杂度。 -
代码逻辑问题:使用
sync.Pool
时,需要确保正确的获取和放回对象逻辑,否则可能导致内存泄漏或对象复用失败,进而影响性能。
综上所述,使用 sync.Pool
前应仔细分析对象的使用模式和生命周期,确保 sync.Pool
的使用能真正带来性能提升。