复杂对象图的快速HashCode

时间:2010-01-14 06:38:50

标签: c# .net 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();
}

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

我的项目需要这些对象的唯一性,我处理这些经常,而中的数据各种方式处理和地方

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

提前致谢 穆奈姆

1 个答案:

答案 0 :(得分: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;

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

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

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