登录
首页 >  Golang >  Go问答

使用sync.Pool来正确管理切片

来源:stackoverflow

时间:2024-03-13 15:33:28 247浏览 收藏

Golang不知道大家是否熟悉?今天我将给大家介绍《使用sync.Pool来正确管理切片》,这篇文章主要会讲到等等知识点,如果你在看完本篇文章后,有更好的建议或者发现哪里有问题,希望大家都能积极评论指出,谢谢!希望我们能一起加油进步!

问题内容

我正在构建一个 go 应用程序来服务数千个 http 请求。服务包括解析输入、处理输入并返回输出。

输入解析包括将json解析为map[string]string列表

如何实现此解析的内存池?

最小可重现示例:

var poolTest *sync.Pool

func init() {
    poolTest = &sync.Pool{
        New: func() interface{} {
            return new([]map[string]string)
        },
    }
}

func Requesthandler (ctx *fasthttp.RequestCtx) {
    poolTestList  := poolTest.Get().(*[]map[string]string)
    input := ctx.PostBody()
    _=json.Unmarshal(input, poolTestList)

    //do something
    print(*(poolTestList))
   
     //clear and return to pool
    (*poolTestList) = (*poolTestList)[:0]
    poolTest.Put(poolTestList)
}

func main() {
    _ = (&fasthttp.Server{
        Handler:        Requesthandler,
        ReadBufferSize: 8192,
        TCPKeepalive: true,
    }).ListenAndServe(":3000")
}

我感到困惑的部分是清除并返回池。

这是正确的方法吗?


解决方案


您的实现通常是正确的,但这里有一些奇怪的事情。首先,你几乎不需要一个指向切片的指针;你似乎在这里绝对不需要一个。您的值应该只是 []map[string]string 而不是 *[]map[string]string

第二,per the examples,最佳实践是在 Get 之后重置池化对象,而不是在 Put 之前。这是最安全的,因为这意味着 Get 不会对其从池中接收的值做出任何潜在不安全的假设。如果项目往往会在池中停留很长时间并且非常大,您也可以同时执行这两种操作(这里可能会导致地图切片的内存使用量非常高,因此这取决于您的用例)。

请注意, //do some 中的内容可能是相关的,因为您正在使用此处的映射和切片,它们的行为符合引用语义。如果任何切片或映射泄漏此方法,您可能会因无意中共享内存而遇到一些潜在问题,这些问题可能很难诊断。

最后,请记住,此代码池化贴图,池化切片。因此,如果这些只是大型地图的简短列表,那么这里的好处可能很小。事实上,即使是一长串地图,也可能很少。我会删除池代码、基准测试和配置文件,并确保您实际上正在优化与性能相关的某些内容。

今天关于《使用sync.Pool来正确管理切片》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

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