英文:
Check if key exists in map storing large values
问题
在Go语言中,要判断一个键k
是否存在于映射M1[k]v
中非常简单。
if v, ok := M1[k]; ok {
// 键存在
}
'v': 非指针类型的值。
如果v
很大,仅仅使用上述方法检查特定键是否存在并不高效,因为它会将值v
加载到内存中(即使我在v
的位置使用空白标识符_
,根据我的理解,请纠正我如果我理解错了)。
是否有一种高效的方法可以检查映射中是否存在某个键(而不需要读取或分配值到内存中)?
我在考虑创建一个新的映射M2[k]bool
来存储信息,并在每次向M1
插入内容时在M2
中进行记录。
英文:
To know a key k
exist in a map M1[k]v
is very straightforward in Go
.
if v, ok := M1[k]; ok {
// key exist
}
'v': a value of a non-pointer type.
If v
is large, To just check if a particular key exists using the above method is not efficient as it will load the value v
in the memory(even if I use a blank identifier _
in the place of v
as per my understanding and please correct me if my understanding is wrong here).
Is there an efficient way in which we can check if a key is present in a Map(without reading/or the value is allocated in the memory)?
I am thinking to create a new map M2[k]bool
to store the information and make an entry in M2
each time I insert something in M1
.
答案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纳秒。当我们将值分配给非空白标识符时,它几乎需要1毫秒(大约慢了十万倍),当值类型的大小约为8 MB时。
英文:
Use if _, ok := M1[k]; ok { }
. If you use the blank identifier, the value will not be "loaded".
Let's write benchmarks to test it:
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
}
}
}
}
Running go test -bench .
, the output is:
BenchmarkNonBlank-8 1497 763278 ns/op
BenchmarkBlank-8 97802791 12.09 ns/op
As you can see, using the blank identifier, the operation takes about 10 ns. When we assign the value to a non-blank identifier, it's almost 1 ms (almost a hundred thousand times slower) when the value type has a size of around 8 MB.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论