【问题标题】:when to resize a hash table?何时调整哈希表的大小?
【发布时间】:2011-06-24 23:21:24
【问题描述】:

在各种哈希表实现中,我看到了可变哈希表何时应该调整大小(增长)的“神奇数字”。通常,这个数字介于每个分配的插槽所添加的值的 65% 到 80% 之间。我假设权衡是更高的数字会带来更多冲突的可能性,而更低的数字会以使用更多内存为代价。

我的问题是这个数字是怎么得出的?

这是任意的吗?基于测试?基于其他一些逻辑?

【问题讨论】:

    标签: algorithm hashtable


    【解决方案1】:

    据推测,大多数人至少开始从一本书(例如,Knuth,第 3 卷)中的数字开始,这些数字是通过测试产生的。根据情况,有些人可能会在之后进行测试,并做出相应的调整——但据我所知,这些可能是少数。

    正如我在previous answer 中概述的那样,“正确”数字还很大程度上取决于您如何解决冲突。无论好坏,这一事实似乎被广泛忽视——人们通常不会选择特别适合他们使用的碰撞解决方案的数字。

    OTOH,我在测试中发现的另一点是它很少会产生很大的不同。您可以在相当广泛的范围内选择数字并获得非常相似的整体速度。最重要的是要小心避免将数字推得太高,尤其是当您使用线性探测之类的方法来解决冲突时。

    【讨论】:

      【解决方案2】:

      我认为您不想考虑表“有多满”(总桶中有多少“桶”具有值),而是要考虑为新项目找到位置可能需要的冲突次数。

      几年前我读过一些编译器书籍(不记得标题或作者),建议只使用链表,直到您拥有超过 10 到 12 个项目。这似乎支持超过 10 次碰撞意味着需要重新调整大小。

      The Design and Implementation of Dynamic. Hashing for Sets and Tables in Icon 建议平均哈希链长度为 5(在该算法中,平均冲突数)足以触发重新哈希。似乎得到了测试的支持,但我不确定我是否正确阅读了论文。

      看来resize的情况主要是测试的结果。

      【讨论】:

      • 调整大小如何减少碰撞次数?较长数组的哈希函数仍然是相同的,所以对于同一个键仍然会发生冲突,对吧?
      • @Core_Dumped - 是的,散列函数保持不变,表中项目的散列值保持不变。但是存储桶的长度会发生变化,因此存储桶项目所在的位置也会发生变化。调整大小意味着更改存储桶数组(通常)的长度,然后重新存储哈希表中的所有项目。每桶链长度平均下降,这意味着更少的冲突。
      【解决方案3】:

      这取决于键。如果您知道您的哈希函数对所有可能的键都是完美的(例如,使用gperf),那么您知道您只会遇到很少的冲突,因此数量会更高。

      但大多数时候,除了它们是文本之外,您对键了解不多。在这种情况下,您必须猜测,因为您甚至没有测试数据来提前弄清楚您的哈希函数的行为。

      所以你希望最好。如果您的哈希函数对键非常不利,那么您将有很多冲突并且永远无法达到增长点。在这种情况下,选择的数字是无关紧要的。

      如果您的哈希函数足够,那么它应该只会产生少量冲突(小于 50%),因此 65% 到 80% 之间的数字似乎是合理的。

      也就是说:除非您的哈希表必须是完美的(= 巨大的大小或大量的访问),否则不要打扰。如果你有十个元素,那么考虑这些问题就是浪费时间。

      【讨论】:

        【解决方案4】:

        据我所知,这个数字是基于经验测试的启发式方法。

        由于散列值的分布相当好,看起来神奇的负载因子——正如你所说的——通常在 70% 左右。较小的负载因子意味着您在浪费空间而没有真正的好处;更高的负载因子意味着您将使用更少的空间,但会花费更多时间来处理哈希冲突。

        (当然,如果您知道哈希值是完美分布的,那么您的负载因子可以是 100%,您仍然不会浪费空间,也不会发生哈希冲突。)

        【讨论】:

          【解决方案5】:

          碰撞高度依赖于数据和使用的哈希函数。

          大多数数字基于启发式或关于哈希值正态分布的假设。 (大约 70% 的 AFAIK 值是可扩展哈希表的典型值,但总是可以构造这样的数据流,这样您会得到更多/更少的冲突)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-12-21
            • 2012-10-14
            • 2021-03-14
            • 2017-06-07
            • 2014-04-21
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多