检查存储大值的映射中是否存在键
Check if key exists in map storing large values
要知道映射 M1[k]v
中存在键 k
在 Go
中非常简单。
if v, ok := M1[k]; ok {
// key exist
}
'v': 一个非指针类型的值。
如果 v
很大,使用上述方法仅检查特定键是否存在效率不高,因为它会将值 v
加载到内存中(即使我使用空白根据我的理解,标识符 _
代替了 v
,如果我的理解有误,请指正)。
是否有一种有效的方法可以检查 Map 中是否存在键(如果没有 reading/or,则值分配在内存中)?
我正在考虑创建一个新地图 M2[k]bool
来存储信息并在每次在 M1
中插入内容时在 M2
中创建一个条目。
使用if _, ok := M1[k]; ok { }
。如果使用空白标识符,该值将不会被“加载”。
让我们编写基准测试它:
var m = map[int][1_000_000]int64{
1: {},
}
func BenchmarkNonBlank(b *testing.B) {
for i := 0; i < b.N; i++ {
if v, ok := m[1]; ok {
if false {
_ = v
}
}
}
}
func BenchmarkBlank(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, ok := m[1]; ok {
if false {
_ = ok
}
}
}
}
运行go test -bench .
,输出为:
BenchmarkNonBlank-8 1497 763278 ns/op
BenchmarkBlank-8 97802791 12.09 ns/op
如您所见,使用空白标识符,操作大约需要 10 ns。当我们将值分配给一个非空标识符时,当值类型的大小约为 8 MB 时,它几乎是 1 毫秒(慢了将近十万倍)。
要知道映射 M1[k]v
中存在键 k
在 Go
中非常简单。
if v, ok := M1[k]; ok {
// key exist
}
'v': 一个非指针类型的值。
如果 v
很大,使用上述方法仅检查特定键是否存在效率不高,因为它会将值 v
加载到内存中(即使我使用空白根据我的理解,标识符 _
代替了 v
,如果我的理解有误,请指正)。
是否有一种有效的方法可以检查 Map 中是否存在键(如果没有 reading/or,则值分配在内存中)?
我正在考虑创建一个新地图 M2[k]bool
来存储信息并在每次在 M1
中插入内容时在 M2
中创建一个条目。
使用if _, ok := M1[k]; ok { }
。如果使用空白标识符,该值将不会被“加载”。
让我们编写基准测试它:
var m = map[int][1_000_000]int64{
1: {},
}
func BenchmarkNonBlank(b *testing.B) {
for i := 0; i < b.N; i++ {
if v, ok := m[1]; ok {
if false {
_ = v
}
}
}
}
func BenchmarkBlank(b *testing.B) {
for i := 0; i < b.N; i++ {
if _, ok := m[1]; ok {
if false {
_ = ok
}
}
}
}
运行go test -bench .
,输出为:
BenchmarkNonBlank-8 1497 763278 ns/op
BenchmarkBlank-8 97802791 12.09 ns/op
如您所见,使用空白标识符,操作大约需要 10 ns。当我们将值分配给一个非空标识符时,当值类型的大小约为 8 MB 时,它几乎是 1 毫秒(慢了将近十万倍)。