我正在编写很多表查找的程序。因此,当我偶然发现Data.Map
(当然),以及Data.HashMap
和Data.Hashtable
时,我正在仔细阅读Haskell文档。我不是哈希算法的专家,在检查包之后,它们看起来都非常相似。因此我想知道:
1:如果有什么主要差异?
2:在大约4000个键值对的地图/表格上进行大量查找的性能最高?
答案 0 :(得分:49)
1:如果有什么主要差异?
Data.Map.Map
是内部的平衡二叉树,因此查找的时间复杂度为O(log n)。我相信它是一个“persistent”数据结构,这意味着它的实现使得变异操作产生了一个新副本,只更新了结构的相关部分。Data.HashMap.Map
在内部是Data.IntMap.IntMap
,而后者则以Patricia树的形式实现;查找的时间复杂度为O(min(n,W)),其中 W 是整数中的位数。它也是“持久的”。Data.HashTable.HashTable
是一个实际的哈希表,查找时间复杂度为O(1)。但是,它是一个可变数据结构 - 操作是就地完成的 - 所以如果你想使用它,你就会陷入IO
monad。2:在大约4000个键值对的地图/表格上进行大量查找的性能最高?
不幸的是,我能给你的最佳答案是“它取决于”。如果从字面上理解渐近复杂性,Data.Map
得到O(log 4000)=约12,Data.HashMap
得O(min(4000,64))= 64,O(1)= 1 Data.HashTable
。但它并没有真正起作用......你必须在代码的上下文中尝试它们。
答案 1 :(得分:11)
Data.Map
和Data.HashMap
之间的明显区别在于前者需要Ord
中的键,后者需要Hashable
个键。大多数公共密钥都是,所以这不是一个决定性的标准。我对Data.HashTable
没有任何经验,所以我无法对此发表评论。
Data.HashMap
和Data.Map
的API非常相似,但Data.Map
导出更多功能,alter
中缺少某些功能,Data.HashMap
以严格和非严格的变体提供,而Data.HashMap
(我假设您的意思是来自unordered-containers的散列映射)在单独的模块中提供了延迟和严格的API。如果您只使用API的公共部分,那么切换实际上是无痛的。
关于效果,unordered-containers的Data.HashMap
查找相当快,最后我测量,显然比Data.IntMap
或Data.Map
更快,尤其是({1}}尚未发布)unordered-containers的HAMT分支。我认为对于插入,它或多或少与Data.IntMap
相当,并且比Data.Map
略快,但我对此有点模糊。
对于大多数任务而言,两者都具有足够的性能,对于那些没有完成任务的任务,您可能还需要量身定制的解决方案。考虑到你专门询问查找,我会给Data.HashMap
边缘。
答案 2 :(得分:2)
Data.HashTable
的文档现在说“使用hashtables包”。有一篇很好的博客文章解释了为什么哈希表是一个很好的包here。它使用ST monad。