golang中地图的大O性能是多少?

时间:2015-04-16 14:24:35

标签: go maps hashtable

"Map types" section of the go language specification描述了地图类型的接口和一般用法以及"Go maps in action" post on The Go Blog随便提及的哈希表和快速查找,添加和删除"。

current runtime/hashmap.go source code将其实现描述为哈希表(通常是分摊的O(1));但是,我不会在语言规范或其他材料中看到任何性能特征(例如Big O性能)的保证。

go语言是否为地图类型或仅接口保证了性能保证(例如,恒定时间插入/查找/删除?)? (与 interfaces implementation 明确分开的Java语言相比。)

3 个答案:

答案 0 :(得分:21)

语言参考没有明确保证地图的性能。有一种隐含的期望,即地图的执行方式与您希望的哈希表一样。我不知道性能保证如何避免模糊指定或不准确。

Big-O复杂度是描述地图运行时间的一种不好的方式:实际上,实际的时钟时间是相关的,而复杂性则不然。从理论上讲,具有来自有限域(例如整数)的密钥的映射在空间和时间上通常是O(1),而具有无限域(例如字符串)的密钥的映射需要散列并且相等性测试的细节包含在成本中,这使得插入和查找最佳情况O(N log N)平均(因为密钥平均大小必须至少为O(log N),以构造具有N个条目的哈希表。除非您在下面得到这些详细信息规范它将是不准确的,并且正确的利益并不值得。

为了保证实际的运行时而不是复杂性,它也很难:有各种各样的目标机器,以及缓存和垃圾收集的混淆问题。

答案 1 :(得分:6)

从我所看到的情况来看,Go Programming Language Specification没有为地图类型提供任何性能保证。 Hash tables通常是O(1)用于插入,查找和删除数据;我们可以假设Go的地图也是如此。

如果您担心地图性能,您可以始终在不同的负载上benchmark代码,并决定是使用Go的地图还是其他一些数据结构。

答案 2 :(得分:2)

准确地说,哈希表的性能是O(1 + n / k)来解决冲突,其中n / k指的是负载因子。将规范声明映射作为密钥数量的非限制性。因此,他们需要动态调整大小并进行部分重新调整以在增长或缩小时保持负载因子。这意味着在O(1)附近可以很容易地实现在恒定大小的映射中查找,但理论上甚至可以保证大量插入或删除。此类操作需要重新分配,部分重新散列和可能的垃圾收集,以保持负载因子和合理的内存使用。