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

6 回复

最起码把代码用 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 后发现程序变慢的情况,可能有以下几个原因:

  1. 对象生命周期不匹配:如果对象在池中存活时间过长,可能会导致内存占用增加,反而影响性能。sync.Pool 适用于短生命周期对象的复用,若对象生命周期较长,则复用效果有限。

  2. 锁竞争:在高并发场景下,sync.Pool 的内部实现涉及锁操作,可能导致性能瓶颈。虽然Go的锁实现相对高效,但在极高并发下仍可能成为性能瓶颈。

  3. 池大小配置不当sync.Pool 没有提供直接设置池大小的接口,其内部通过复杂的算法来管理对象。如果对象数量远超过池的管理能力,可能会导致频繁的GC,反而降低性能。

  4. GC压力:虽然 sync.Pool 旨在减少GC压力,但在某些情况下,由于池的使用方式不当,可能导致对象频繁进出池,反而增加GC的复杂度。

  5. 代码逻辑问题:使用 sync.Pool 时,需要确保正确的获取和放回对象逻辑,否则可能导致内存泄漏或对象复用失败,进而影响性能。

综上所述,使用 sync.Pool 前应仔细分析对象的使用模式和生命周期,确保 sync.Pool 的使用能真正带来性能提升。

回到顶部