我必须将一个对象与同一类的原始属性进行比较。 意思是,我必须比较这些:
struct Identifier
{
string name;
string email;
}
带有两个字符串名称和电子邮件。 我知道我可以为姓名和电子邮件创建一个新的标识符实例并将其传递给 equals() 。我的应用程序必须非常快并且节省资源。
我知道通过哈希码进行比较不是一个好方法,因为正如here所解释的那样,存在冲突。但碰撞对我来说没问题,我只需要它快点。
那么,
1) 通过 GetHashCode 进行比较(检查两个对象的哈希码是否相同)比 Equals() 更快?
2)我是否应该创建一个用于比较的两个值的新标识符实例,而是创建一个直接获取值的新方法?例如
struct Identifier {
string name;
string email;
bool Equals(string name, string email) {
// todo comparison via hashcode or equals
}
}
如果将哈希代码保存在
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周期。
通过 GetHashCode 进行比较(检查两个对象的哈希码是否相同) 相同)比 Equals() 更快?
您似乎混淆了这两个概念。
GetHashCode
的目的不是寻求两个对象实例之间的相等,它的存在只是为了让每个对象可以轻松地为可能依赖它的任何外部资源提供哈希码值。
另一方面,Equals
是为了确定平等。应该是两个为 equals 产生 true
的方法提供相同的哈希码,而不是相反。
object.GetHashCode
的文档提供了很好的解释:
两个相等的对象返回相等的哈希码。然而, 反之则不然:相等的哈希码并不意味着对象 相等,因为不同(不相等)的对象可以具有相同的哈希值 代码。此外,.NET Framework 不保证默认的 GetHashCode 方法的实现,以及该方法的值 .NET Framework 版本和平台之间的返回可能有所不同,例如 作为 32 位和 64 位平台。由于这些原因,请勿使用 此方法的默认实现为唯一对象标识符 用于散列目的。由此产生两个后果:
- 您不应该假设相等的哈希码意味着对象相等。
- 您永远不应该在应用程序域之外保留或使用哈希代码 它被创建,因为同一个对象可能会散列 应用程序域、流程和平台。
如果您想检查两个实例之间的相等性,我绝对建议实现
IEquatable<T>
并覆盖 object.GetHashCode
。
顺便说一句 - 我看到你正在使用
struct
。您应该注意,struct
在 C# 中与在 C++ 或 C 中具有不同的语义,我希望您了解它们。