首页 文章

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

提问于
浏览
4

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

struct Identifier
{
    string name;
    string email;
}

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

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

所以,

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.

2 回答

  • 5

    如果将它们保存在 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周期 .

  • 6

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

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

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

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

    两个相等的对象返回相等的哈希码 . 但是,相反的情况并非如此:相等的哈希码并不意味着对象相等,因为不同(不相等)的对象可以具有相同的哈希码 . 此外,.NET Framework不保证GetHashCode方法的默认实现,并且此方法返回的值可能因.NET Framework版本和平台(例如32位和64位平台)而异 . 由于这些原因,请不要将此方法的默认实现用作散列目的的唯一对象标识符 . 由此产生两种结果:您不应该假设相等的哈希码意味着对象相等 . 您永远不应该在创建它的应用程序域之外持久存储或使用哈希代码,因为相同的对象可能会跨应用程序域,进程和平台进行哈希处理 .

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

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

相关问题