复杂对象图的快速HashCode

Abd*_*nim 4 .net c# performance hash-code-uniqueness

我有一个非常复杂的对象,我需要获得这些对象的唯一性.一种解决方案可以通过覆盖来完成GetHashCode().我已经实现了以下代码:

public override int GetHashCode()
{
    return this._complexObject1.GetHashCode() ^
           this._complexObject2.GetHashCode() ^
           this._complexObject3.GetHashCode() ^
           this._complexObject4.GetHashCode() ^
           this._complexObject5.GetHashCode() ^
           this._complexObject6.GetHashCode() ^
           this._complexObject7.GetHashCode() ^
           this._complexObject8.GetHashCode();
}
Run Code Online (Sandbox Code Playgroud)

这些复杂对象也会覆盖 GetHashCode()并执行类似的操作.

我的项目需要这些对象的唯一性,我经常处理这些对象,并且内部数据也会以各种方式和位置发生变化.

我需要一种更快的方法来找到这些复杂对象的唯一性,这需要考虑性能内存.

在此先感谢
Munim

Jon*_*eet 10

鉴于你的评论,这听起来像你可能试图依靠的GetHashCode 自行确定唯一性.不要那样做.哈希并不意味着是唯一的-它的意思是不可能有两个不相等的对象将返回相同的数值,但并非不可能.如果您尝试检查一组对象没有重复项,则必须使用Equals.

请注意,使用XOR作为哈希码可能会使您更有可能获得哈希冲突,具体取决于所涉及的各个哈希值.特别是,它使任何两个相等的字段"相互抵消".我通常使用这种形式:

int hash = 17;
hash = hash * 31 + field1.GetHashCode();
hash = hash * 31 + field2.GetHashCode();
hash = hash * 31 + field3.GetHashCode();
hash = hash * 31 + field4.GetHashCode();
...
return hash;
Run Code Online (Sandbox Code Playgroud)

......但即便如此,这肯定不能保证唯一性.您应该使用GetHashCode()排除平等,然后使用Equals来检查任何可能相等值的实际平等.

现在你的问题提到了速度 - 这听起来像是使用剖析器和一些基准测试的完美场所.你确定这是一个瓶颈吗?如果您有许多不同类型的所有计算哈希值,您是否发现其中哪一个是问题的最大贡献者?

一些优化将取决于您使用数据的确切方式.如果你发现花费了大量的时间来重新计算你知道没有改变的值的哈希值,你可以缓存哈希码......虽然当有些字段本身引用复杂对象时,这显然变得更加棘手.您可以缓存"叶节点"哈希,特别是如果这些叶节点不经常更改(但它们的使用可能会有所不同).