5

要知道k映射中存在的键M1[k]v非常简单Go

if v, ok := M1[k]; ok {
    // key exist
}

'v' : 非指针类型的值。

如果v很大,仅使用上述方法检查特定键是否存在效率不高,因为它会将值加载到v内存中(即使我根据我的理解使用空白标识符_代替,v如果我的这里的理解是错误的)。

是否有一种有效的方法可以检查 Map 中是否存在键(无需读取/或在内存中分配值)?

我正在考虑创建一个新地图M2[k]bool来存储信息并在M2每次插入内容时在M1.

4

1 回答 1

7

使用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 毫秒(几乎慢了十万倍)。

于 2022-01-02T17:07:22.123 回答