【问题标题】:Algorithmic complexity of Data.HashtableData.Hashtable 的算法复杂度
【发布时间】:2016-04-12 20:51:46
【问题描述】:

我正在尝试编写一个利用哈希的函数(用于 A* 的实现)。

经过一番研究,我发现事实上的标准是Data.Map

但是,在阅读API文档时,我发现:O(log n). Find the value at a key.

https://downloads.haskell.org/~ghc/6.12.2/docs/html/libraries/containers-0.3.0.0/Data-Map.html

事实上,文档通常表明大 O 倍显着低于标准哈希的 O(1)。

然后我找到了Data.HashTablehttps://hackage.haskell.org/package/base-4.2.0.2/docs/Data-HashTable.html 这个文档没有直接提到大 O,让我相信它可能符合我的期望。

我有几个问题: 1)这是正确的吗?是 O(lookupInDataHashTable) = O(1) 吗? 2) 鉴于Data.Map 效率低下,我为什么要使用它? 3) 是否有更好的库满足我的数据结构需求?

【问题讨论】:

  • 在实践中,您应该对 O(1) 与 O(log n) 算法进行基准测试(前者可能有更大的常数),Data.MapData.IntMap 可能是一个不错的选择。如果您希望Data.HashTable 检查hackage.haskell.org/package/hashtables 通常我认为最重要的是最终的内存使用情况。

标签: haskell data-structures hashtable time-complexity


【解决方案1】:

Data.HashTable 已被弃用,您不会在当前的base 中找到它。

它已被弃用,因为它与 hashtables 相比表现不佳。

但是,hashtablesData.HashTable 都是可变实现,而 Data.MapData.HashMap 是不可变的。

Haskell 中的可变哈希映射类似于桶数组或其他语言中的开放寻址解决方案。不可变映射基于树或尝试。一般来说,不可变的关联容器不能通过 O(1) 修改来实现。

那么为什么要使用不可变映射呢?

首先,API 在 Haskell 中更加方便。我们不能在纯函数中使用可变映射,只能在 IO 或 ST 操作中使用。

第二,不可变映射可以在线程之间安全地共享,这通常是一个关键特性。

第三,在实践中,可变映射和不可变映射之间的性能差异可能是微不足道的,即。 e.它不会显着影响整体程序性能。 O(log n) 也受可用内存的限制,因此与 O(1) 相比,我们没有得到惊人的渐近差异。特别是,Data.HashMap 使用 16 个分支的 trie,因此 trie 深度实际上不可能超过 6 或 7。

第四,由于我不完全理解的原因(更优化的库?来自 GHC 的更好优化?),不可变映射可以变得更快;我尝试了几次将Data.HashMap 替换为来自hashtables 的可变映射,但之后性能总是有点差。

【讨论】:

  • 大型和小型可变映射通常对您来说表现更差吗?
  • 大型可变映射表现更差。特别是,被注释掉的 trieToNode here 对于具有 300k-500k 元素的地图的表现要差得多。
【解决方案2】:

鉴于 Data.Map 效率低下,我为什么还要使用它?

它可能效率不高,但它支持任何类型的带有 Ord 实例的键,即使是那些不能散列为整数的键。

O(lookupInDataHashTable) = O(1) 吗?

通常是的。 “lookupInDataHashTable”的工作流程和对应的大O表示法的表现是:

  1. 散列密钥。整数:O(1),字符串:O(字符串长度)
  2. 使用哈希访问一个 IOArray,得到一个包含所有具有相同哈希的键值对的列表。 O(1)
  3. 在列表中查找密钥。 O(列表的长度)

因此,除非您有很长的字符串作为键,否则查找函数可以保证 O(1) 的性能。

是否有更好的库满足我的数据结构需求?

这取决于您的密钥类型。对于不同的整数,Data.IntMap 最好,对于其他可散列类型,Data.HashMap 表现出不错的性能,否则您别无选择,只能使用 Data.Map。

【讨论】:

  • 我的密钥是字符串类型
  • @AbrahamP 在这种情况下,您可能需要考虑使用(路径压缩)trie。
  • @AbrahamP,你的钥匙有多长?这确实有所作为。此外,在放弃纯度及其使用哈希表的优势之前,您应该查看哈希映射、trie 变体等是否足够快。
猜你喜欢
  • 1970-01-01
  • 2021-04-22
  • 1970-01-01
  • 2013-11-01
  • 2011-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多