3

有没有办法在 Go中分配一个未初始化的切片?一种常见的模式是创建一个给定大小的切片作为缓冲区,然后只使用它的一部分来接收数据。例如:

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

当分配大量缓冲区时,此初始化可能会累加,因为规范声明它将默认在分配时初始化数组。

4

2 回答 2

2

您可以从bufs.Cache.Get获取非零字节缓冲区(或查看并发安全版本)。从文档CCache

注意:Get 返回的缓冲区不保证归零。例如,将缓冲区传递给 io.Reader 是可以的。如果您需要一个归零缓冲区,请使用 Cget。

于 2013-06-24T13:25:13.830 回答
0

从技术上讲,您可以通过在 go 运行时之外分配内存并使用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)
    }
}
于 2013-06-24T12:52:25.577 回答