在地图中进行多次添加/删除后,在地图上的测距速度比预期的慢。
考虑以下代码
package main
import (
"fmt"
"time"
)
func main() {
test := make(map[int]bool)
for i := 0; i < 1000000; i++ {
test[i] = true
}
for k := range test {
delete(test, k)
}
test[0] = true
fmt.Printf("test len(): %d\n", len(test))
now := time.Now()
for range test {
}
fmt.Printf("range took %v\n", time.Since(now))
}
在我的系统上,循环测试映射(包含1个条目)需要3.5毫秒。这是一个问题,因为我们在生产环境中运行类似的代码,并且一段时间后,每个映射都有数百万个已删除的条目。
GC似乎无济于事,我能想到的唯一解决方案是将整个地图设置为nil,然后重新制作它。还有其他方法吗?
答案 0 :(得分:2)
我希望性能会根据地图的最大尺寸大致缩放,但是我不希望随着时间的推移进行更多的写入和删除操作,性能会变得更糟。有两个部分;是时候检查所有存储桶了,这将根据地图的大小进行缩放,并且产生结果的时间将根据当前存在的条目数进行缩放。
但是添加和删除内容不应进一步更改它。
https://play.golang.org/p/Ouj-3MuZvVt
另请参阅https://github.com/golang/go/issues/20135,该问题跟踪“地图在删除后不会缩小”。
如果您确实需要遍历地图的一小部分,则可能需要制作一个仅包含您要保留的项目的新地图,但这并不是花费您时间的插入/删除操作,它是地图已经请注意,如果您添加和删除1000个项目(而不是添加一百万个项目然后删除它们),则时间消耗要小得多。