1

I’m appending the values of a map into an existing slice.

The code’s like (the s is a slice that already has some elements in it):

for key, value := range m {
    s = append(s, value)
}

As far as I know, slices in Go double their sizes when needed. I could let it double the capacity of itself, but it’ll happen several times a loop, which probably is bad for performance.

In this case, I know the exact space needed, that is, len(m). How do I “reserve” the space for a slice, like that in C++? I want the reallocation to happen just once.

  • 3
    did you read through https://blog.golang.org/slices? it explains some approaches – Thomas Jungblut Apr 29 '21 at 07:06
  • Does this answer your question? [Does Go have no real way to shrink a slice? Is that an issue?](https://stackoverflow.com/questions/16748330/does-go-have-no-real-way-to-shrink-a-slice-is-that-an-issue) – advay rajhansa Apr 29 '21 at 07:08
  • 1
    Create a new slice with enough size to hold values from the old slice + the inserted ones, then `copy` all of it over. This would guarantee only 1 reallocation. – super Apr 29 '21 at 07:48

1 Answers1

3

You allocate memory for an object with make, like (play):

s := make([]string, len(m))
for i, v := range m {
    s[i] = v
}

Alternatively, you can create a slice of length zero, but with enough capacity to hold n values. Here, append will never need to be allocate new memory, if the number of items appended does not exceed capacity (play).

s := make([]string, 0, len(m))
for _, v := range m {
    s = append(s, v)
}

If you like to dive into slices more visually, this blog post may help:

If you want to manually enlarge an slices with element you would need to:

  • create a new slice of desired capacity (and length)
  • use copy to copy elements over

Example on play.

miku
  • 181,842
  • 47
  • 306
  • 310
  • I already have a slice that has some elements in it. What should I do in this case? – Константин Ван Apr 29 '21 at 07:09
  • 1
    @КонстантинВан, updated my answer - you'll need to allocate, then copy - similar to what append would do internally, but manually with the capacity of your choice. – miku Apr 29 '21 at 07:12
  • @КонстантинВан, I added play links to the examples, e.g. for copy here: https://play.golang.org/p/tK-71BmqLnE – miku Apr 29 '21 at 08:47