4

私はかなり複雑なオブジェクトを持っており、これらのオブジェクトの一意性を取得する必要があります。1つの解決策は、をオーバーライドすることで実行できます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()して実行します。

私のプロジェクトでは、これらを頻繁に扱うこれらのオブジェクトの一意性が必要であり、内部のデータもさまざまな方法や場所で変化します。

パフォーマンスメモリを考慮する必要があるこれらの複雑なオブジェクトの一意性を見つけるためのより高速な方法が必要です。

よろしくお願いします
Munim

4

1 に答える 1

10

あなたのコメントを考えると、一意性を判断するためにGetHashCode自体に依存しようとしているように思われます。そうしないでください。ハッシュは一意であるという意味ではありません。2つの等しくないオブジェクトが同じ値にハッシュされる可能性は低いですが、不可能ではありません。オブジェクトのセットに重複がないことを確認しようとしている場合は、Equalsも使用する必要があります。

ハッシュコードにXORを使用すると、関係する個々のハッシュ値によっては、ハッシュの衝突が発生する可能性が高くなることに注意してください。特に、それは任意の2つの等しいフィールドを「互いにキャンセル」します。私は通常、次のフォームを使用します。

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

今、あなたの質問は速度について言及しています-これはプロファイラーといくつかのベンチマークテストを使用するのに最適な場所のように聞こえます。これがボトルネックであると確信していますか?すべての計算ハッシュ値に多くの異なるタイプがある場合、これらのうちどれが問題の最大の原因であるかを見つけましたか?

一部の最適化は、データの使用方法に正確に依存します。変更されていないことがわかっている値のハッシュの再計算に多くの時間が費やされている場合は、ハッシュコードをキャッシュできます...ただし、それ自体が複雑なオブジェクトを参照するフィールドがある場合は、明らかに注意が必要になります。特にそれらのリーフノードが頻繁に変更されない場合は、「リーフノード」ハッシュをキャッシュできる可能性があります(ただし、それらの使用法は異なる可能性があります)。

于 2010-01-14T07:19:48.863 に答える