Matt Joiner
Matt Joiner

Reputation: 118480

Allocate uninitialized slice

Is there some way to allocate an uninitialized slice in Go? A frequent pattern is to create a slice of a given size as a buffer, and then only use part of it to receive data. For example:

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

This initialization can add up when lots of buffers are being allocated, as the spec states it will default initialize the array on allocation.

Upvotes: 3

Views: 139

Answers (2)

zzzz
zzzz

Reputation: 91223

You can get non zeroed byte buffers from bufs.Cache.Get (or see CCache for the concurrent safe version). From the docs:

NOTE: The buffer returned by Get is not guaranteed to be zeroed. That's okay for e.g. passing a buffer to io.Reader. If you need a zeroed buffer use Cget.

Upvotes: 2

cthom06
cthom06

Reputation: 9635

Technically you could by allocating the memory outside the go runtime and using unsafe.Pointer, but this is definitely the wrong thing to do.

A better solution is to reduce the number of allocations. Move buffers outside loops, or, if you need per goroutine buffers, allocate several of them in a pool and only allocate more when they're needed.

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)
    }
}

Upvotes: 0

Related Questions