通过 Equals 或 HashCode 进行比较。哪个更快?

Comparison via Equals or HashCode. which is faster?

我必须比较具有相同 class 原始属性的对象。 意思是,我必须比较那些:

struct Identifier
{
    string name;
    string email;
}

使用名称和电子邮件这两个字符串。 我知道我可以为姓名和电子邮件创建一个新的标识符实例并将其传递给 equals()。我的应用程序必须非常快速且节省资源。

我知道通过哈希码进行比较不是一个好方法,因为正如 所解释的,存在冲突。但是碰撞对我来说没问题,我只需要它快点。

所以,

1) 通过 GetHashCode 进行比较(检查两个对象的哈希码是否相同)比 Equals() 更快?

2) 我是否应该为比较创建两个值的标识符的新实例,创建一个直接获取值的新方法?例如

struct Identifier {
  string name;
  string email;

  bool Equals(string name, string email) {
      // todo comparison via hashcode or equals
  }
}

I would use the Equals() and GetHashCode() method generated by resharper.

is comparison via GetHashCode (check if the hashcode of both objects are the same) faster than Equals()?

您似乎混淆了这两个概念。 GetHashCode 的目的不是 寻求两个对象实例之间的相等性 ,它的存在只是为了让每个对象可以轻松地为可能依赖的任何外部资源提供哈希码值它。

Equals,另一方面,是用来判断是否相等的。应该是两种方法产生 true 等于,提供相同的哈希码,但不是相反。

The documentation on object.GetHashCode 提供了很好的解释:

Two objects that are equal return hash codes that are equal. However, the reverse is not true: equal hash codes do not imply object equality, because different (unequal) objects can have identical hash codes. Furthermore, the .NET Framework does not guarantee the default implementation of the GetHashCode method, and the value this method returns may differ between .NET Framework versions and platforms, such as 32-bit and 64-bit platforms. For these reasons, do not use the default implementation of this method as a unique object identifier for hashing purposes. Two consequences follow from this:

  • You should not assume that equal hash codes imply object equality.
  • You should never persist or use a hash code outside the application domain in which it was created, because the same object may hash across application domains, processes, and platforms.

如果你想检查两个实例之间的相等性,我绝对建议实施 IEquatable<T> 并覆盖 object.GetHashCode.

附带说明 - 我看到您使用的是 struct。您应该注意到 struct 在 C# 中的语义与在 C++ 或 C 中的语义不同,我希望您知道它们。

如果将哈希码保存在 Identifier 实例中(见下文),比较哈希码可能会更快。但是,这与比较相等性不同。

比较哈希码可以让您检查两个项目是否绝对彼此相等:当您获得不同的哈希码时,您就知道这一点。

但是,当哈希码相等时,您无法对相等性做出明确的声明:各项可能相等或不相等。这就是为什么基于散列的容器必须始终遵循散列码比较(直接或间接)以及相等性比较。

尝试像这样进行比较:

struct Identifier {
    string name;
    string email;
    int nameHash;
    int emailHash;
    public Identifier(string name, string email) {
        this.name = name;
        nameHash = name.GetHashCode();
        this.email = email;
        emailHash = email.GetHashCode();
    }
    bool Equals(string name, string email) {
        return name.GetHashCode() == nameHash
            && email.GetHashCode() == emailHash
            && name.equals(this.name)
            && email.equals(this.email);
    }
}

与预先计算的哈希码进行比较会使实际的相等性比较短路,因此当大多数比较最终返回 false 时,您可以节省一些 CPU 个周期。