【发布时间】:2015-04-07 19:10:52
【问题描述】:
Scala 有一个 TrieMap 集合。
什么是 TrieMap,与 HashMap 相比,它的优势/劣势是什么?
【问题讨论】:
-
绝对不是重复的。您最大的优势是 Scala TrieMaps 提供了高效、一致的迭代器,可以在一个时间点捕获 trie 中的所有元素。
标签: scala
Scala 有一个 TrieMap 集合。
什么是 TrieMap,与 HashMap 相比,它的优势/劣势是什么?
【问题讨论】:
标签: scala
Scala TrieMap 是基于 trie 的并发 可扩展地图实现。与普通的 trie 映射不同,Scala TrieMap 具有高效、非阻塞、O(1) 时间的 snapshot 操作(以及经过略微优化的 readOnlySnapshot)操作。
TrieMap 的绝对性能略低于 JDK8 ConcurrentHashMap,但优点是它提供了一致的迭代器,这是并发数据结构通常不具备的。这意味着您可以在一个时间点捕获 trie 中的所有元素(性能数字和分析here)。如果您需要一次捕获所有元素(例如,在 UI 中列出其所有元素,或持续分析它们),则应使用 TrieMap。
【讨论】:
O(1) time snapshot operation 是如何解释的。
TrieMap 的新快照(即克隆)将在恒定的时间内创建(即在相同的时间内与您存储的密钥数量无关)。稍后,当您尝试访问该快照或原始 TrieMap 中的某些键时,TrieMap 的相关部分将被延迟复制。
the relevant parts of the TrieMap will be lazily duplicated. 这是否意味着当从克隆/快照访问密钥时,它不再是哈希图中的O(1) get()?这个lazy duplication 的运行时间复杂度是多少?底层树的高度,如 O(lgN)?
lazy duplication 在实际get() 之前的运行时间复杂度是多少? get() 在lazy duplication 之后的运行时间复杂度是多少?
TrieMap 是使用 trie 数据结构的 Map,本质上是浅树。例如,如果您有一个 32 位散列,您可以将其分解为例如 4 乘 8 的部分,并且在树的每个级别上,您最多可以分支到 256 个子树。显然,由于哈希的大小固定(假设很少发生冲突),这给出了 O(1) 的性能。
可以有效地使 trie 结构不可变,重用 trie 的结构来创建具有添加或删除元素的新 trie。 时间/内存对 GC 影响的相对性能在很大程度上取决于实现和负载,因此我会说运行基准测试而不是尝试通用答案。尽管对于没有不变性要求的单线程,经典的 hashmap 通常会产生更好的平均性能和较差的最坏情况性能。
作为旁注,我会提到,因为 trieMap 也使用哈希,它也是一个哈希图,所以我建议将其称为 trie 支持的哈希图与数组支持的哈希图。
【讨论】: