【问题标题】:Why is '397' used for ReSharper GetHashCode override?为什么 ReSharper GetHashCode 覆盖使用“397”?
【发布时间】:2010-09-11 06:59:52
【问题描述】:

和你们中的许多人一样,我使用 ReSharper 来加快开发过程。当您使用它来覆盖类的相等成员时,它为GetHashCode() 生成的代码生成如下:

    public override int GetHashCode()
    {
        unchecked
        {
            int result = (Key != null ? Key.GetHashCode() : 0);
            result = (result * 397) ^ (EditableProperty != null ? EditableProperty.GetHashCode() : 0);
            result = (result * 397) ^ ObjectId;
            return result;
        }
    }

当然我有一些自己的成员,但我想知道为什么是 397?

  • 编辑:所以我的问题的措辞会更好,397 素数除了是素数之外还有什么“特殊”吗?

【问题讨论】:

    标签: hash resharper hash-code-uniqueness


    【解决方案1】:

    可能是因为 397 是一个足够大的素数,会导致结果变量溢出并在一定程度上混合散列位,从而提供更好的散列码分布。 397 并没有什么特别之处可以将它与其他相同大小的素数区分开来。

    【讨论】:

    • 而 397 很高兴。难道我们不都只想快乐吗?
    • 好的,但是为什么它必须是素数,为什么它必须是那个精确的量级?如果它必须是素数,为什么不是 2 或 2147483647?我猜想得到很好的突变(这种乘法的唯一原因是突变)我们不需要数字是素数。我们需要乘数具有相对相同的数字或零和一,最好没有明确的模式。 397=110001101b 符合。仍然不确定幅度。
    • 正如尼克所说,它并没有什么特别之处。它不需要那么大,这只是一个足够大的数字,当您计算哈希时,结果会溢出(因为 GetHashCode() 返回一个 Int32)。选择素数只是对分布有帮助,我没有数学学位,所以我不会尝试解释它,但是乘以素数的结果比乘以任何其他任意数字的结果分布得更好。
    • @AndriyK 2 是一个非常小的哈希表。您的负载因子将是基于素数的哈希表大小的最小负载因子。随着负载因子接近 0,哈希表中未使用区域的比例增加,但搜索成本不一定降低。所以它实际上是哈希表的最差大小。换句话说,您可以将* 397 视为定义哈希表的大小,这就是 FNV 哈希算法所做的(但它建议 1099511628211 用于 64 位 哈希,它不会适用于 32 位整数)。
    【解决方案2】:

    resharper 使用的哈希看起来像是FNV 哈希的变体。 FNV 经常使用不同的素数来实现。 There's a discussion on the appropriate choice of primes for FNV here.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-13
      • 2010-09-20
      • 1970-01-01
      • 2011-05-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多