Reputation: 101
I'm wondering if uint8 or uint16 Go map keys will be stored as 1/2 bytes or they will have uint32/64 memory allocations regardless of specifying something smaller?
Upvotes: 1
Views: 340
Reputation: 417552
Maps are hashmaps in Go, their internals is non-trivial. Common sense tells the key size should make a difference, but since this is not in the language specification, measure it yourself.
Check How to get memory size of variable in Go? for how to measure size of arbitrary variables.
For example create a test:
const size = 250
func getMap8(size int) map[uint8]uint16 {
m := make(map[uint8]uint16, size)
for i := uint8(0); i < uint8(size); i++ {
m[i] = uint16(i)
}
return m
}
func getMap16(size int) map[uint16]uint16 {
m := make(map[uint16]uint16, size)
for i := uint16(0); i < uint16(size); i++ {
m[i] = i
}
return m
}
func getMap32(size int) map[uint32]uint16 {
m := make(map[uint32]uint16, size)
for i := uint32(0); i < uint32(size); i++ {
m[i] = uint16(i)
}
return m
}
func getMap64(size int) map[uint64]uint16 {
m := make(map[uint64]uint16, size)
for i := uint64(0); i < uint64(size); i++ {
m[i] = uint16(i)
}
return m
}
func Benchmark8(b *testing.B) {
for n := 0; n < b.N; n++ {
getMap8(size)
}
}
func Benchmark16(b *testing.B) {
for n := 0; n < b.N; n++ {
getMap16(size)
}
}
func Benchmark32(b *testing.B) {
for n := 0; n < b.N; n++ {
getMap32(size)
}
}
func Benchmark64(b *testing.B) {
for n := 0; n < b.N; n++ {
getMap64(size)
}
}
Running it with go test -bench . -benchmem
, the output is:
Benchmark8-8 95862 11210 ns/op 3188 B/op 4 allocs/op
Benchmark16-8 107731 11017 ns/op 3572 B/op 4 allocs/op
Benchmark32-8 150126 8496 ns/op 4980 B/op 4 allocs/op
Benchmark64-8 144655 8959 ns/op 6644 B/op 4 allocs/op
So the map size is indeed smaller if the key size is smaller, but obviously the key and value size together determine the final size.
Size of a map of type map[uint8]uint16
with 250 entries is about 3188 bytes, a map with uint16
key type is 3572 bytes, a map with uint32
key type is 4980 bytes, and a map with uint64
key type is 6644 bytes.
Upvotes: 6