我有一个程序,它使用缓冲池来减少代码中一些性能敏感部分的分配。
像这样的事情:播放链接 https://play.golang.org/p/c_gsqBcbE-
// some file or any data source
var r io.Reader = bytes.NewReader([]byte{1,2,3})
// initialize slice to max expected capacity
dat := make([]byte, 20)
// read some data into it. Trim to length.
n, err := r.Read(dat)
handle(err)
dat = dat[:n]
// now I want to reuse it:
for len(dat) < cap(dat) {
dat = append(dat, 0)
}
log.Println(len(dat))
// add it to free list for reuse later
// bufferPool.Put(dat)
我总是分配固定长度的切片,保证其大于所需的最大大小。我需要将大小减小到实际数据长度才能使用缓冲区,但我还需要将其再次设置为最大大小,以便下次需要时读取它。
我知道扩展切片的唯一方法是append
,这就是我正在使用的。不过,循环感觉超级脏。并且可能效率低下。我的基准测试表明这并不可怕,但我觉得必须有更好的方法。
我只知道一点关于切片的内部表示,但如果我只能以某种方式覆盖长度值而不实际添加数据,那就太好了。我真的不需要将其归零或其他什么。
有更好的方法来实现这一点吗?
将切片“扩展”至其容量只是切片表达式 https://golang.org/ref/spec#Slice_expressions,并将容量指定为高索引。高索引不需要小于长度。限制是:
对于数组或字符串,如果满足以下条件,则索引在范围内:0 <= low <= high <= len(a)
,否则它们超出范围。对于切片,索引上界是切片容量cap(a)
而不是长度。
Example:
b := make([]byte, 10, 20)
fmt.Println(len(b), cap(b), b)
b = b[:cap(b)]
fmt.Println(len(b), cap(b), b)
输出(尝试一下去游乐场 https://play.golang.org/p/KL6Ag5smNt):
10 20 [0 0 0 0 0 0 0 0 0 0]
20 20 [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)