Created
September 18, 2019 17:09
-
-
Save xeoncross/6427a669deb769875d76ea0515587085 to your computer and use it in GitHub Desktop.
How much memory does a slice of random strings actually take?
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"math/rand" | |
"unsafe" | |
) | |
// Thanks to Kale, Andrei, and Jaden on gophers slack | |
// so the size actually taken up by the string is the length of the string and | |
// then the size of the memory allocated for the slice holding references to | |
// the strings is 8 or 16 bytes times the capacity | |
// unsafe.Sizeof returns the compile time size of a type. It will return the | |
// exact same size for unsafe.Sizeof("") and unsafe.Sizeof("really long string") | |
// because strings are a header that point to data. It doesn't tell you the size | |
// of the data the header points to. | |
// This can also get more complicated if some of the elements are the same | |
// string or slices of larger strings because they could be sharing the | |
// underlying data. For your example with randomly generated strings that math should be correct. | |
// I don't know precisely about padding, but I do remember this oddity: | |
// https://play.golang.org/p/IqSI1DJV2YX (which may or may not reflect a reality about padding) | |
const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
func RandStringBytes(n int) string { | |
b := make([]byte, n) | |
for i := range b { | |
b[i] = letterBytes[rand.Intn(len(letterBytes))] | |
} | |
return string(b) | |
} | |
func main() { | |
number := 100000 | |
var size uint64 | |
var values = make([]string, number) | |
size += uint64(unsafe.Sizeof(values)) | |
for i := 0; i < number; i++ { | |
values[i] = RandStringBytes(100) | |
size += uint64(len(values[i])) | |
} | |
size += uint64(unsafe.Sizeof("")) * uint64(number) | |
fmt.Println(uint64(unsafe.Sizeof(values))) | |
fmt.Println("total size", size) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
https://play.golang.org/p/OUYz1dVo76r
Also related, but not the same, is the size of an array: https://stackoverflow.com/questions/44257522/how-to-get-memory-size-of-variable-in-go/44258164#44258164