Go 中,除了使用缓存池,如何减少 slice 的动态分配?

比如,有这样一个函数:

func foo(n int) []byte {
    bar := make([]byte, n)
    ...do some thing with b
    return bar
}

bar := make([]byte, n)是一处动态内存分配,函数的其他部分不会再对bar的大小进行修改了。这种情况下有没有方法消除bar := make([]byte, n)这处动态内存分配?

阅读 4.7k
3 个回答

这个问题只能从你自身的需求来讲,每次调用foo如果期望一个独立的slice返回,那么只能这么办了。如果不是这样,可以考虑以下方法:

  • 申明一个生命周期在函数foo以外的slice,每次复用这个slice(前提是你需要保证这样没问题)

func bar(length int) func(int) []byte {
    s := make([]byte, length)
    return func(n int) []byte {
        //do something with s
        return s
    }
}
  • 类似于redis的内存管理,初始化一个大slice,每次使用大slice的一部分

var gs = make([]byte, verylong)
var lastPosition int
func foo(n int) []byte {
    last := lastPosition
    s := gs[last:last+n]
    //do something with s
    updateLastPosition()
    //如果要保证thread safe需要自己做额外的工作
    //需要处理last+n > verylong的情况
    return s
}

可以bar := make([]byte, n, capacity),预先指定一个容量。

这种问题是很单纯的自己想多的。

如果是Read Only 的可以使用楼上的方法。

如果不是,那么别想多了。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题