What is the Big O performance of maps in golang?

huangapple go评论85阅读模式
英文:

What is the Big O performance of maps in golang?

问题

《Go语言规范中的“Map类型”部分》描述了map类型的接口和一般用法,《The Go Blog上的“Go maps in action”文章》中提到了哈希表以及“快速查找、添加和删除”。

《当前的runtime/map.go源代码》将其实现描述为哈希表(通常为摊还的O(1));然而,我没有在语言规范或其他资料中看到任何性能特性的保证(比如大O性能)。

Go语言对于map类型是否提供任何性能保证(比如常数时间的插入/查找/删除),还是只提供接口保证?(与Java语言相比,接口实现是明确分离的。)

英文:

The "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 casually mentions hash tables and "fast lookups, adds, and deletes".

The current runtime/map.go source code describes its implementation as a hashtable (which are typically amortized O(1)); however, I don't see any guarantee of performance characteristics (such as Big O performance) in the language specification or other materials.

Does the go language make any performance guarantees (e.g. constant-time insertion/lookup/deletion) for map types or only interface guarantees? (Compare to the Java language where interfaces and implementations are clearly separate.)

答案1

得分: 46

语言参考并没有明确保证映射的性能。人们隐含地期望映射的性能与哈希表的性能相似。我不明白性能保证如何避免变得模糊不清或不准确。

使用大O复杂度来描述映射的运行时间是不准确的:实际上,实际的时钟时间是相关的,而复杂度并不重要。从理论上讲,键来自有限域(如整数)的映射在空间和时间上都是O(1)的,而键来自无限域(如字符串)的映射需要哈希和相等性测试的具体实现来计算成本,这使得插入和查找的平均最佳情况复杂度为O(N log N)(因为平均而言,键的大小至少为O(log N),以构建一个包含N个条目的哈希表)。除非在规范中正确描述这些细节,否则结果将是不准确的,而且得到正确结果的好处也不明显。

要提供关于实际运行时间而不是复杂度的保证也很困难:目标机器的范围很广,而且还有缓存和垃圾回收等问题的干扰。

英文:

The language reference doesn't make explicit guarantees about the performance of maps. There's an implicit expectation that maps perform like you expect hash-tables to perform. I don't see how a performance guarantee would avoid being either vaguely specified or inaccurate.

Big-O complexity is a poor way to describe run-times for maps: practically speaking the actual clock time is relevant and complexity isn't. Theoretically, maps with keys from finite domains (such as ints) are trivially O(1) in space and time, and maps with keys with infinite domains (such as strings) require hashing and the specifics of equality testing to be included in the cost, which makes inserts and lookups best case O(N log N) on average (since the keys have to be at least O(log N) in size on average to construct a hash table with N entries. Unless you get these details right in the specification it's going to be inaccurate, and the benefit of getting it right isn't clearly worth it.

To provide guarantees about actual run-time rather than complexity it'd be also be difficult: there's a wide range of target machines, as well as the confounding problems of caching and garbage collection.

答案2

得分: 10

准确来说,哈希表的性能是O(1 + n/k),其中n/k是负载因子。Go语言规范声明了映射中键的数量不受限制。因此,当映射的大小增加或缩小时,它们需要进行动态调整大小和部分重新哈希操作,以保持负载因子。这意味着在常量大小的映射中,查找操作可以很容易地达到接近O(1)的性能,但对于大规模的插入或删除操作,理论上无法保证O(1)的性能。这些操作需要重新分配内存、部分重新哈希和可能的垃圾回收操作,以保持负载因子和合理的内存使用。

英文:

To be precise hash tables performance is O(1 + n/k) to resolve collisions, where n/k refer to load-factor. Go spec declare maps as non-restrictive in keys quantity. So they need dynamic resizing with partly rehashing to keep load-factor when growing or shrinking. This means near O(1) can be easily achieved for lookup in constant size maps, but can't even theoretically be guaranteed for massive insertion or deletions. Such operations want reallocation, partial rehashing and possible garbage collections to keep load-factor and reasonable memory usage.

答案3

得分: 8

根据我所看到的,Go编程语言规范对于映射类型(map types)并没有做出任何性能保证。一般来说,哈希表在插入、查找和删除数据方面的时间复杂度都是O(1);我们可以假设Go的映射类型也是如此。

如果你对映射的性能有所担忧,你可以通过在不同负载下进行基准测试来决定是否使用Go的映射类型或其他数据结构。

英文:

From what I can see, the Go Programming Language Specification does not make any performance guarantees for map types. Hash tables in general are O(1) for inserting, looking up and deleting data; we can assume that this is also true for Go's maps.

If you are worried about map performance, you can always benchmark your code on different loads and decide, whether to use Go's maps or some other data structure.

huangapple
  • 本文由 发表于 2015年4月16日 22:24:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/29677670.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定