【问题标题】:Fast HashCode of a Complex Object Graph复杂对象图的快速哈希码
【发布时间】:2011-01-04 23:27:27
【问题描述】:

我有一个非常复杂的对象,我需要获得这些对象的唯一性。一种解决方案可以通过覆盖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() 并执行类似的操作

我的项目需要这些对象的唯一性,我非常经常处理这些对象,并且内部的数据也以各种方式更改和地点

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

提前致谢
穆尼姆

【问题讨论】:

  • 如果数据发生变化,GetHashCode() 可能是错误的开始 - 此外,它只能保证不相等(它不能用于测试平等)。
  • 谢谢 Marc,我没有执行测试相等性我使用 GetHashCode() 来检查对象是否不相等,这就是我需要做的
  • 只是想检查一下。不过,我不确定是否有魔术棒的答案。您可以通过缓存值并在发生更改时删除缓存的值来做一些事情,但这在复杂的图表中很棘手(因为您需要检查所有子对象)。

标签: c# .net performance hash-code-uniqueness


【解决方案1】:

鉴于您的评论,听起来您可能正在尝试单独依靠 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() 排除 相等性,然后使用Equals 检查任何可能相等的值的实际相等性。

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

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

【讨论】:

    猜你喜欢
    • 2012-07-17
    • 1970-01-01
    • 2014-07-29
    • 2010-12-11
    • 2012-08-28
    • 1970-01-01
    • 1970-01-01
    • 2019-04-02
    • 2012-07-05
    相关资源
    最近更新 更多