Fabien
Fabien

Reputation: 13406

In go, is it worth avoiding creating slices of size 0?

I have a program in which I'm going to make lots and lots of slices, some of which might be empty:

nb := something() // something might return 0
slices = append(slices, make([]int, nb))

Does make([]int, 0) allocates some memory and is, thus, less memory efficient than a nil slice although they share the same behavior ? By how much ?

If so, is it worth doing a test to avoid useless allocations, or is the CPU time cost of the test not worth the saving in memory (or any other reason not to do so) ?

var sl slice
nb := something()
if nb > 0 {
    sl = make([]int, nb)
}
slices = append(slices, sl)

Upvotes: 1

Views: 531

Answers (2)

thwd
thwd

Reputation: 24808

Does make([]int, 0) allocates some memory

Yes, it allocates a slice header but no backing array. If the slice header doesn't escape the current scope it may be allocated on the stack.

less memory efficient than a nil slice

In terms of memory used, they're the same.

is it worth doing a test to avoid useless allocations

In general yes, the 3 or 4 instructions it takes to compare an int are nothing compared to the cycles you'd need to do a memory allocation and initialization.

Upvotes: 3

chill
chill

Reputation: 16888

There is no difference in the allocated memory between

var a []T // nil slice

and

a := make([]T, 0) // zero-length, zero-capacity, non-nil slice

The difference is in the slice header content. In the second case the slice pointer contains some fixed address, same for all 0-sized allocations.

If this code is in a performance critical part of the program, the difference makes ... quite a difference. In the first case you do zero the slice header, in the second case you go through 3-4 function calls, some range checks for cap and length, etc. before malloc returns a pointer to the zero base.

Upvotes: 4

Related Questions