3 回答
TA贡献2016条经验 获得超9个赞
一种常见的方法是让客户端将现有的 []byte(或其他)作为参数传递给某个调用/函数/方法。例如:
// The returned slice may be a sub-slice of dst if dst was large enough
// to hold the entire encoded block. Otherwise, a newly allocated slice
// will be returned. It is valid to pass a nil dst.
func Foo(dst []byte, whatever Bar) (ret []byte, err error)
另一种方法是从缓存和/或例如池中获取新的 [] 字节(如果您更喜欢该概念的后一个名称),并依靠客户端将使用过的缓冲区返回到此类“回收站”。
顺便说一句:考虑到这一点,你做得对。在可以合理地重用 []byte 缓冲区的地方,有可能降低 GC 负载,从而使您的程序性能更好。有时差异可能很关键。
TA贡献1860条经验 获得超9个赞
您可以在每次操作结束时重新划分缓冲区。
buffer = buffer[:0]
然后,extendAndSliceBuffer
如果需要增长,您的函数将具有最有可能可用的原始后备数组。如果没有,您将遭受新的分配,而您无论如何都可能会得到它extendAndSliceBuffer
。
总的来说,我认为更简洁的解决方案是像@jnml 所说的那样做,让用户在关心性能时传递他们自己的缓冲区。如果他们不关心性能,那么您不应该使用全局变量,而是根据需要简单地分配缓冲区,并在超出范围时将其释放。
TA贡献1772条经验 获得超8个赞
我有一个全局(但未导出)字节切片,它从 1024 个元素开始,并根据需要加倍增长。
这就是你的问题。你的包中不应该有这样的全局变量。
通常最好的方法是使用带有附加功能的导出结构。缓冲区应驻留在未导出的结构中。这样用户就可以实例化它并让垃圾收集器在他们放手时清理它。
您还希望避免需要这样的全局变量,因为它会妨碍单元测试。单元测试应该能够像用户一样实例化导出的结构,并且每次测试时都这样做。
还取决于什么样的缓冲你的需要,bytes.Buffer
因为它已经提供了可能是有用的io.Reader
和io.Writer
功能。bytes.Buffer
还会自动增长和缩小其缓冲区。在buffer.go 中,您会看到各种调用以b.Truncate(0)
“重置以恢复空间”注释进行收缩。
- 3 回答
- 0 关注
- 218 浏览
添加回答
举报