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

mic*_*idk 4 c# comparison performance

我必须将一个对象与同一个类的原始属性进行比较.意思是,我必须比较那些:

struct Identifier
{
    string name;
    string email;
}
Run Code Online (Sandbox Code Playgroud)

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

我知道通过哈希码进行比较不是一个好方法,因为这里解释的是冲突.但碰撞对我来说没问题,我只需要快速.

所以,

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

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

struct Identifier {
  string name;
  string email;

  bool Equals(string name, string email) {
      // todo comparison via hashcode or equals
  }
}
Run Code Online (Sandbox Code Playgroud)

我会使用resharper生成的Equals()和GetHashCode()方法.

das*_*ght 6

如果将哈希代码保存在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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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


Yuv*_*kov 5

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

你似乎混淆了这两个概念.GetHashCode其目的不是寻求两个对象实例之间的相等,它就是这样,每个对象都可以轻松地为可能在其上传递的任何外部资源提供哈希码值.

Equals另一方面,是确定平等.它应该是两个产生true等于的方法,提供相同的哈希码,但不是相反的方式.

文档object.GetHashCode提供了一个很好的解释:

两个相等的对象返回相等的哈希码.但是,相反的情况并非如此:相等的哈希码并不意味着对象相等,因为不同(不相等)的对象可以具有相同的哈希码.此外,.NET Framework不保证GetHashCode方法的默认实现,并且此方法返回的值可能因.NET Framework版本和平台(例如32位和64位平台)而异.由于这些原因,请不要将此方法的默认实现用作散列目的的唯一对象标识符.由此产生两种后果:

  • 您不应该假设相等的哈希码意味着对象相等.
  • 您永远不应该在创建它的应用程序域之外持久存储或使用哈希代码,因为相同的对象可能会跨应用程序域,进程和平台进行哈希处理.

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

作为旁注 - 我看到你正在使用struct.你应该注意到structC#中的语义与C++或C中的语义不同,我希望你能够意识到它们.