【问题标题】:Deal with collisions using another hash function?使用另一个哈希函数处理冲突?
【发布时间】:2013-12-18 23:41:17
【问题描述】:

我的问题不是关于双重哈希技术http://en.wikipedia.org/wiki/Double_hashing,这是一种解决冲突的方法。它是关于处理字符串哈希表中现有的冲突。说,我们有一个冲突:同一个桶中有几个字符串,所以现在我们必须通过桶检查字符串。计算另一个散列函数以进行快速字符串比较似乎是有意义的(比较散列值以快速拒绝)。哈希键可以延迟计算并与字符串一起保存。你用过这种技术吗?你能提供一个参考吗?如果不是,您是否认为由于性能增益值得怀疑而不值得这样做?一些注意事项:

  1. 我把标签“Java”,因为我在 Java 中进行测量: String.hashCode() 在大多数情况下优于 String.equals() (顺便说一句,大大优于手动哈希码计算:hashCode = 31 * hashCode + strInTable.charAt( i));
  2. 当然,对于任何字符串比较都可以提出同样的问题,不一定是哈希表中的字符串。但我正在考虑一种特殊情况,其中有大量字符串保存在哈希表中。
  3. 如果桶中的字符串有些相似(如在 Rabin-Karp 算法中),这可能是有意义的。在一般情况下寻求您的意见。

【问题讨论】:

  • 这看起来高度依赖于上下文。我会做现实的测试用例并比较性能指标。
  • @Julius 同意。只是想先检查一下。也许我的问题没有意义:如果哈希码检查总是更快,那么 String.equals() 将使用它来实现。虽然大数据可以产生影响。

标签: java string hash collision


【解决方案1】:

许多基于散列的集合存储集合中每个项目的散列值,前提是每个项目的散列在添加到集合时已经计算,并且在散列中查找项目的代码集合必须知道它的哈希值,比较哈希值将是降低错误命中成本的一种快速简便的方法。例如,如果有一个 16 桶哈希表,其中包含四个字符串,每个字符串 1,000 个字符,并且将搜索大量 1,000 个字符的字符串,这些字符串除了最后几个字符之外都与表条目中的一个匹配,更多超过 6% 的搜索会命中包含近似匹配字符串的存储桶,但会命中包含 32 位 hashCode 与正在搜索的字符串匹配的字符串的存储桶的比例要小得多。由于比较几乎相同的字符串的成本很高,因此比较完整的 32 位哈希码很有帮助。

如果一个人有可能需要存储在哈希表中并与其他此类集合匹配的大型不可变集合,则让此类集合计算和缓存更长的哈希函数并让它们的equals 方法比较在进一步进行之前,这些较长哈希函数的结果。在这种情况下,计算较长的散列函数通常几乎与计算较短的散列函数一样快。此外,不仅在较长的哈希码上进行比较会大大降低误报导致不必要的“深度”比较的风险,而且计算较长的哈希函数并将它们组合到报告的hashCode()中可以大大降低强相关哈希的危险碰撞。

【讨论】:

    【解决方案2】:

    仅当比较(查找)的数量与条目数量相比较大时,比较散列才有意义。您将需要一个大哈希(32 位是不够的;您至少需要 128 位),而且计算起来会很昂贵。您可能希望通过对存储桶的大量探测来分摊每个字符串的散列成本。

    至于是否值得,它高度依赖于上下文。找出答案的唯一方法是实际使用您的数据并比较两种方法的性能。

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 2015-04-07
      • 1970-01-01
      • 1970-01-01
      • 2021-08-10
      • 2023-04-04
      • 2013-06-16
      • 2019-03-25
      • 1970-01-01
      相关资源
      最近更新 更多