性能Haskell散列结构。
我正在写程序,做了很多表查找。 就这样,当我偶然发现Data.Map
(当然),还有Data.HashMap
和Data.Hashtable
时,我正在Data.Map
Haskell文档。 我不是散列algorithm方面的专家,在检查包之后,他们看起来都非常相似。 因此我想知道:
1:如果有什么重大区别?
2:在大约4000个键值对的地图/表上,查找量最大的是哪一个?
1:如果有什么主要区别?
-
Data.Map.Map
在内部是一个平衡的二叉树,所以查找的时间复杂度是O(log n)。 我相信这是一个“ 持久的 ”数据结构,这意味着它的实现使得变化操作产生一个新的副本,只更新结构的相关部分。 -
Data.HashMap.Map
在内部是一个Data.IntMap.IntMap
,它又被实现为Patricia树; 其查找的时间复杂度为O(min(n,W)),其中W是整数中的位数。 它也是“持久的”。 -
Data.HashTable.HashTable
是一个实际的哈希表,其查询的时间复杂度为O(1)。 然而,这是一个可变的数据结构 – 操作是在原地完成的 – 所以如果你想使用它,你就被困在IO
monad中。
2:在大约4000个键值对的地图/表上,查找量最大的是哪一个?
不幸的是,我可以给你的最好的答案是“这取决于”。 如果从字面上Data.Map
渐近复杂性, Data.Map
,O(min( Data.HashMap
))= 64, Data.HashMap
O(log 4000)= 12, Data.Map
O(1)= 1。 但是这并不是真的那样…你必须在你的代码中尝试它们。
Data.Map
和Data.HashMap
区别在于前者需要Ord
键,后者是Hashable
键。 大多数常用密钥都是,所以这不是一个决定性的标准。 我没有任何与Data.HashTable
经验,所以我不能对此发表评论。
Data.HashMap
和Data.Map
的API非常相似,但Data.Map
导出更多的函数,其中一些像Data.HashMap
中没有Data.HashMap
,另外一些提供了严格和非严格的变体,而Data.HashMap
(I假设你的意思是来自无序容器的散列表)在单独的模块中提供了惰性和严格的API。 如果你只使用API的公共部分,切换是非常痛苦的。
关于性能, 无序容器的 Data.HashMap
查找速度相当快,最后我测量,它明显快于Data.IntMap
或Data.Map
,特别适用于(尚未发布的) 无序容器的 HAMT分支。 我认为插入,它是或多或less与Data.IntMap
相Data.IntMap
并且比Data.Map
快一点,但是我有点模糊。
对于大多数任务来说,这两者都是充分的performance,对于那些不是那些任务的人来说,无论如何你可能都需要一个量身定制的解决scheme。 考虑到你特别要求查询,我会给Data.HashMap
的边缘。
Data.HashTable
的文档现在说“使用哈希表包”。 有一个很好的博客文章解释了为什么哈希表是一个很好的包。 它使用ST monad。