登录
首页 >  Golang >  Go问答

sync.Pool 的不当行为

来源:stackoverflow

时间:2024-02-24 22:33:21 220浏览 收藏

在IT行业这个发展更新速度很快的行业,只有不停止的学习,才不会被行业所淘汰。如果你是Golang学习者,那么本文《sync.Pool 的不当行为》就很适合你!本篇内容主要包括##content_title##,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

了解sync.pool 我为它编写了两种不同的新方法:

  1. 返回一个切片;
  2. 返回一个要切片的指针;
  3. 只需分配一个不带池的新切片(用于比较性能);

基准让我惊讶

  1. 6ns/op 和 1 次分配
  2. 17ns/op 和 0 分配
  3. 130ns/op 和 1 次分配

请解释一下为什么 1 和 3 之间有这么大的差异,因为两者都分配内存? 为什么第一个分配?

package main

import (
    "bytes"
    "sync"
)

func main() {}

type MyBuffer struct {
    pool sync.Pool
}

func New() *MyBuffer {
    return &MyBuffer{pool: sync.Pool{
        New: func() any {
            buf := make([]int, 0, 128)
            return &buf
        },
    }}
}

func New2() *MyBuffer {
    return &MyBuffer{pool: sync.Pool{
        New: func() any {
            buf := make([]int, 0, 128)
            return buf
        },
    }}
}

func Fill[S ~[]E, E any](buf *S) {
    var some E
    for i := 0; i < cap(*buf); i++ {
        *buf = append(*buf, some)
    }
}

func BenchmarkAlloc(b *testing.B) {
    b.RunParallel(func(p *testing.PB) {
        for p.Next() {
            // Get buf
            buf := make([]int, 0, 128)
            // fill
            Fill(&buf)
            // Reset
            buf = buf[:0]
        }
    })
}

func BenchmarkPoolPtr(b *testing.B) {
    mb := New()
    b.RunParallel(func(p *testing.PB) {
        for p.Next() {
            // Get buf
            buf, _ := mb.pool.Get().(*[]int)
            // fill
            Fill(buf)
            // reset
            *buf = (*buf)[:0]
            // put
            mb.pool.Put(buf)
        }
    })
}

func BenchmarkPoolNoPtr(b *testing.B) {
    mb := New2()
    b.RunParallel(func(p *testing.PB) {
        for p.Next() {
            // Get buf
            buf, _ := mb.pool.Get().([]int)
            // fill
            Fill(&buf)
            // reset
            buf = buf[:0]
            // put
            mb.pool.Put(&buf)
        }
    })
}

正确答案


我认为在第一种情况下,分配是对您的切片的引用。在第三种情况中,分配的是完整的切片。 当你查看分配的大小时,它是 32 B/op 与 1024 B/op 因此分配是对切片的引用,当变量是指针时不需要。

好了,本文到此结束,带大家了解了《sync.Pool 的不当行为》,希望本文对你有所帮助!关注golang学习网公众号,给大家分享更多Golang知识!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>