dictionary - 分配给映射键多少内存?即map [uint16] uint16是每个键2个字节还是存储为uint32/64?

标签 dictionary go memory

我想知道uint8或uint16 Go映射键是否将存储为1/2字节,或者它们将具有uint32/64内存分配,而不管指定的内容是否更小?

最佳答案

map 是Go中的哈希图,其内部结构并不复杂。常识告诉您 key 大小应该有所不同,但是由于这不在语言规范中,因此请自己进行测量。
检查How to get memory size of variable in Go?以了解如何测量任意变量的大小。
例如创建一个测试:

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)
    }
}
使用go test -bench . -benchmem运行它,输出为:
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
因此,如果键大小较小,则映射大小确实会较小,但是很明显,键和值大小共同决定了最终大小。
包含250个条目的map[uint8]uint16类型的映射的大小约为3188字节,uint16 key 类型的映射为3572字节,uint32 key 类型的映射为4980字节,uint64 key 类型的映射为6644字节。

关于dictionary - 分配给映射键多少内存?即map [uint16] uint16是每个键2个字节还是存储为uint32/64?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65688365/

相关文章:

Python:如何在行和列的值之间创建对应矩阵?

swift - 从 NSDictionary 切换到字典

session - 如何在不同的包中使用 Golang 中的 Gorilla Session

c++ - mongodb内存泄漏通过C++驱动程序插入文档

python - 如何使用同一字典的另一个键设置字典值

python - 将字典转换为元组,并在元组内添加其他元素

types - golang 中的通用 slice 类型?

go - 如何将任何结构作为参数发送给方法并返回结构?

python - 将C++中的数据映射到内存并以Python读取数据

大数据集的 Python 内存错误