Hi everyone.
I have an example https://play.golang.org/p/nNYiliFZVI but i dont understand why cap(s) = 8 not 4 after append new value to it.
Many thanks
Hey @thanhngvpt, you can check this out, it’s a good read to do with slice usage and internals
https://blog.golang.org/go-slices-usage-and-internals.
At the very least for your question, read from this point onwards:
growing slices
t := make([]byte, len(s), (cap(s)+1)*2) // +1 in case cap(s) == 0
<- this is the basic idea though. Which in your case is cap(s) = 3, + 1 = 4, * 2 = 8.
Many thanks @radovskyb. But when i change type of slice from int to string https://play.golang.org/p/VFm94O9jjz, its cap = 6, Can you explain why?
Hey @thanhngvpt,
When I run them both locally, I receive the same capacity of 8 for both, which leads me to believe that there is probably an old cached version of a string example similar to your example, that’s been run on the playground in the past, so it’s showing a version from when append used a different algorithm.
I could be very wrong and if somebody else knows why, please correct me.
However for example, if you were to create both slices with a length of 40 instead of 3, they will both give you the same capacity of 80 afterwards, even on the playground, not one with 80 and one with 60.
Actually ignore my last reply. I just realized it must be because of the architecture of the machine running the examples on the playground, for example:
s1 := make([]int64, 3)
s1 = append(s1, 4)
fmt.Printf("len %d, cap %d\n", len(s1), cap(s1)) // cap 6
s2 := make([]string, 3)
s2 = append(s2, "a")
fmt.Printf("len %d, cap %d\n", len(s2), cap(s2)) // cap 6
But:
s1 := make([]int32, 3)
s1 = append(s1, 4)
fmt.Printf("len %d, cap %d\n", len(s1), cap(s1)) // cap 8
s2 := make([]string, 3)
s2 = append(s2, "a")
fmt.Printf("len %d, cap %d\n", len(s2), cap(s2)) // cap 6
Once again though if anybody knows different, please explain it for @thanhngvpt.
Edit, once again too I think there’s something else to it, since in these 2 examples, the output is different, so it must be based on the initial length of the slice too.
Starting at length 3: https://play.golang.org/p/iaBAFFR1jz
Starting at length 4: https://play.golang.org/p/_uNaxJV0iW
One last thing.
I am actually quite unsure now what the answer is, since the size of the integer really shouldn’t make a difference, especially since in all of my examples above, the only time the capacities at the end are different is when you use initial length of 3.
When starting with an initial length of 1, 2 or even 4, the capacities all end up the same, but not with 3. That’s very strange.
Edit: I just asked on the gopher slack channel and this is a response I got from @dominikh:
"slices regrow by different factors at different sizes, and capacities get rounded up so they make proper use of the allocated memory, as memory gets allocated in fixed chunks
but it’s an implementation detail, and not one you should have to care about"
Many thanks @radovskyb i think its depend on the number of byte that every data types taken. but that seem not clear with me, i’ll find out more.
This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.