什么是一个重写的System.Object.GetHash code最好的算法?是一个、最好的、重写、算法

2023-09-02 01:16:09 作者:淺唱、一世繁华

在.NET System.Object.GetHash code 方法是用在很多地方,在整个.NET基础类库。尤其是发现当一个集合的项目快速或确​​定的平等。是否有关于如何贯彻落实 GetHash code 重写我的自定义类,所以我不降低性能标准算法/最佳做法?

In .NET System.Object.GetHashCode method is used in a lot of places, throughout the .NET base class libraries. Especially when finding items in a collection fast or to determine equality. Is there a standard algorithm/ best practice on how to implement the GetHashCode override for my custom classes so I don't degrade performance?

推荐答案

我经常去的东西,如在乔希布洛赫的神话般的的有效的Java 。它的快速和创建pretty的好的哈希是不会引起冲突。选择两个不同的素数,例如17和23,和做的:

I usually go with something like the implementation given in Josh Bloch's fabulous Effective Java. It's fast and creates a pretty good hash which is unlikely to cause collisions. Pick two different prime numbers, e.g. 17 and 23, and do:

public override int GetHashCode()
{
    unchecked // Overflow is fine, just wrap
    {
        int hash = 17;
        // Suitable nullity checks etc, of course :)
        hash = hash * 23 + field1.GetHashCode();
        hash = hash * 23 + field2.GetHashCode();
        hash = hash * 23 + field3.GetHashCode();
        return hash;
    }
}

编辑:正如评论指出的那样,你可能会发现,最好选择一个大的质而非繁殖。显然486187739是好的......虽然我已经看到有少量倾向于使用素数最多的例子,至少有类似的算法,其中经常使用的非质数。在不相当,FNV例子后,例如,我用这显然很好地工作数 - 但最初的值不是一个素数。 (倍增常数的是的黄金,虽然我不知道怎么挺重要的一点是。)

As noted in comments, you may find it's better to pick a large prime to multiply by instead. Apparently 486187739 is good... and although most examples I've seen with small numbers tend to use primes, there are at least similar algorithms where non-prime numbers are often used. In the not-quite-FNV example later, for example, I've used numbers which apparently work well - but the initial value isn't a prime. (The multiplication constant is prime though. I don't know quite how important that is.)

这是比 XOR的普遍做法好荷兰国际集团散列codeS主要有两个原因。假设我们有一个类型有两个 INT 字段:

This is better than the common practice of XORing hashcodes for two main reasons. Suppose we have a type with two int fields:

XorHash(x, x) == XorHash(y, y) == 0 for all x, y
XorHash(x, y) == XorHash(y, x) for all x, y

顺便说一下,在较早的算法是目前所采用的C#编译为匿名类型之一。

By the way, the earlier algorithm is the one currently used by the C# compiler for anonymous types.

编辑:此页面使相当多的选择。我想对于大多数情况下,上面是足够好,这是令人难以置信的容易记住和正确的。 href="http://eternallyconfuzzled.com/tuts/algorithms/jsw_tut_hashing.aspx#fnv"> FNV 替代也同样简单,但