有没有办法在Go中分配未初始化的slice?一种常见的模式是创建给定大小的片作为缓冲区,然后仅将其中一部分用于receive数据。例如:
b := make([]byte, 0x20000) // b is zero initialized
n, err := conn.Read(b)
// do stuff with b[:n]. all of b is zeroed for no reason
这种初始化可以在分配大量缓冲区时加起来,因为spec表示默认情况下会在分配时初始化数组。
答案 0 :(得分:2)
您可以从bufs.Cache.Get获取非归零字节缓冲区(或者参见CCache
以获取并发安全版本)。来自docs:
注意:Get 返回的缓冲区不保证归零。这对于例如将缓冲区传递给io.Reader。如果需要使用归零缓冲区,请使用Cget。
答案 1 :(得分:0)
从技术上讲,你可以通过在运行时之外分配内存并使用unsafe.Pointer
,但这绝对是错误的。
更好的解决方案是减少分配数量。将缓冲区移到循环外部,或者,如果需要每个goroutine缓冲区,则在池中分配多个缓冲区,并在需要时分配更多缓冲区。
type BufferPool struct {
Capacity int
buffersize int
buffers []byte
lock sync.Mutex
}
func NewBufferPool(buffersize int, cap int) {
ret := new(BufferPool)
ret.Capacity = cap
ret.buffersize = buffersize
return ret
}
func (b *BufferPool) Alloc() []byte {
b.lock.Lock()
defer b.lock.Unlock()
if len(b.buffers) == 0 {
return make([]byte, b.buffersize)
} else {
ret := b.buffers[len(b.buffers) - 1]
b.buffers = b.buffers[0:len(b.buffers) - 1]
return ret
}
}
func (b *BufferPool) Free(buf []byte) {
if len(buf) != b.buffersize {
panic("illegal free")
}
b.lock.Lock()
defer b.lock.Unlock()
if len(b.buffers) < b.Capacity {
b.buffers = append(b.buffers, buf)
}
}