【问题标题】:Is map lookup in Elixir O(1)?Elixir O(1)中的地图查找吗?
【发布时间】:2016-12-14 18:11:38
【问题描述】:

基于哈希表的 dict/map 结构提供O(1) 查找时间。然而,我一直看到,在 Elixir 中,找到匹配的函数头比在地图中查找内容要快。

例如,Elixir 的 String.Unicode compiles a list of unicode characters into many function heads,因此通过查找 upcase 的函数头来回答“é 的大写版本是什么”。

我不知道为什么这比在地图中查找“é”的单个 upcase 函数头更快或更节省内存。

同样,在“Metaprogramming Elixir”中展示如何构建 I18n 库时,Chris McCord 为每个翻译键指定了自己的函数头,并说:

“通过为每个翻译映射生成函数头,我们再次让虚拟机接管以进行快速查找。”

Elixir 中的映射不提供 O(1) 查找吗? 是在 O(1) 中查找匹配函数吗?为什么选择为许多函数头编译一个静态列表而不是仅仅将它存储在一个映射中?

【问题讨论】:

  • 请记住,复杂性分析不是速度。一个 O(1) 函数的运行速度可能比另一个快十倍。无论如何,散列不是 O(1)。在某些情况下它可能会接近或摊销到 O(1)(概率为 O(1)),但碰撞总是会将其推向 O(n)。
  • @paxdiablo 我理解复杂性!= 速度,这是一个很好的观点。至于碰撞,我看不出它们是如何向 O(N) 推进的。哈希表将限制每个桶的密钥数量 - 例如,最多 10 个。所以在桶中查找永远不会超过 10 次检查,因此 O(1),对吗?使用一个好的散列算法,重新散列的需要应该越来越少 - 例如,每次我们重新散列时,我们必须做两倍于上次的工作,但我们需要花费两倍的时间才能这样做,所以它摊销到 O (1)。如果不知何故新的密钥一直在同一个桶中,这是一个糟糕的哈希算法,对吧?
  • @Nathan,如果允许您限制数据,所有算法都变为 O(1)。复杂性分析适用于任意数据。您可以通过例如使用散列的散列将问题推到更远的地方,但是,没有数据限制,问题将永远存在。
  • @paxdiablo :) 是的,但我相当确定限制每个桶的键数量对于拥有表获得 O(1) 性能是必要的。我不是说限制散列中的项目数量,只是当桶太满时我们重新散列所有内容。我已经实现了一个散列,并在nathanmlong.com/2015/10/reimplementing-rubys-hash 上写过它——也许可以跳到“我们实现 O(1) 了吗?”我想也许我们以某种方式相互误解了——你听起来好像你知道你在说什么,我很确定我也知道。 :)

标签: elixir


【解决方案1】:

Elixir 映射不是 flat 基于散列表的数据结构。小地图是地图有 O(log n) 查找的哈希树。毕竟,基于不可变哈希表的数据结构的更新成本非常高,这是“构建”这些数据结构之一的主要方法。更改一个值将需要您更新仅包含 1 个项目的新地图。它们基于 Rich Hickey 的持久哈希图,这是一种哈希数组映射的 trie。

函数头匹配复杂度是O(n) 最坏情况,但可以由编译器以我不完全理解的方式进行优化。在某些情况下,它可以将一些功能头模式变成一棵树。但是因为函数头匹配没有总顺序,并且必须按照定义的顺序匹配,所以优化的数量非常有限。您可能只是幸运地使用了非常低的函数头匹配部分,并且还在函数头匹配顺序的树中。

头部匹配的每一步都非常轻量级和高度优化,其中地图仍然很新,并且需要进行一些性能优化。例如,如果键是复杂/嵌套的,则哈希函数的复杂性并不简单(但是,简单的整数具有非常快的哈希函数)。但是在您的 unicode 示例中,我敢打赌,根据其对 id 的排序方式,unicode 标准将尽可能多的常用字符放在前面。这可能使 VM 很容易优化并让您获得非常良好的查找时间。我敢肯定,如果您查找一个晦涩的字母表,您的复杂性就会改变。

但是,一个不只是动态生成具有函数匹配的模块作为查找数据的方式的原因是,您会破坏全局状态,特别是 code_server 模块。一些查找可能会更快,但随着数据结构变大,加速可能会减慢。

【讨论】:

  • 您的意思是哈希树查找O(log n) 而不是O(n log n)
  • @Dogbert 我也认为O(n log n) 对于地图来说效率太低了。
猜你喜欢
  • 1970-01-01
  • 2011-07-17
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
  • 2011-08-09
相关资源
最近更新 更多