golang 中 maps 的 Big O 性能如何?

What is the Big O performance of maps in golang?

"Map types" section of the go language specification describes the interface and general usage of map types and the "Go maps in action" post on The Go Blog随便提一下哈希表和"fast lookups, adds, and deletes"。

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

go 语言是否对地图类型或仅接口做出任何性能保证(例如恒定时间insertion/lookup/deletion?) 】 保证? (与 Java 语言相比,其中 接口 实现 明显分开。)

据我所见,Go Programming Language Specification does not make any performance guarantees for map types. Hash tables插入、查找、删除数据一般都是O(1);我们可以假设 Go 的地图也是如此。

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

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

语言参考未明确保证地图的性能。有一种隐含的期望,即映射的执行方式与您期望 hash-tables 的执行方式一样。我看不出性能保证如何避免被含糊地指定或不准确。

Big-O 复杂度是描述地图 运行 时间的糟糕方式:实际上,实际时钟时间是相关的,而复杂度不是。从理论上讲,具有来自有限域(例如 ints)的键的映射在 space 和时间中是平凡的 O(1),并且具有具有无限域(例如字符串)的键的映射需要散列和相等性测试的细节是包含在成本中,这使得插入和查找的最佳情况平均为 O(N log N)(因为键的大小平均必须至少为 O(log N) 才能构造具有 N 个条目的哈希 table . 除非您在规范中获得正确的这些细节,否则它将不准确,而且获得正确的好处显然不值得。

要提供关于实际 运行 时间而不是复杂性的保证,这也很困难:目标机器范围广泛,以及缓存和垃圾收集的混杂问题。