4

検索するオブジェクトといくつかの検索設定に基づいて、いくつかの検索結果をキャッシュしたいと思います。

ただし、これによりかなり長いキャッシュキーが作成されるため、ショートカットを作成すると思い、それを使用GetHashCode()すると思いました。

だから私は疑問に思っていGetHashCode()ました、私が非常に長い文字列を持っているか、これだけが異なる場合でも、常に異なる数を生成します:「a」の代わりに「ä」

いくつかの弦を試してたところ、答えはイエスのようでしたが、GetHashCode()動作を理解していないと、私が正しいと実感できません。

そして、それはあなたが準備ができていないときにポップアップするものの1つなので(クライアントは間違った検索のためにキャッシュされた結果を見ています)、私は確認したいです...

編集:MD5が機能する場合は、もちろんGetHashCodeを使用しないようにコードを変更できます。目標は、元の文字列よりも短い(> 1000文字)文字列を取得することです。

4

5 に答える 5

9

あなたGetHashCode()はユニークであることを期待することはできません。

http://kenneththorman.blogspot.com/2010/09/c-net-equals-and-gethashcode.htmlで、衝突の可能性を調査する優れた記事があります。調査結果は、「異なる文字列に対して同じハッシュコードを返すためのGetHashCode()の呼び出しの最小数は、565回の反復後であり、ハッシュコードの衝突を取得する前の反復の最大数は296390回でした。」

実装の契約を理解できるようGetHashCodeに、以下は次のMSDNドキュメントからの抜粋ですObject.GetHashCode()

ハッシュ関数には、次のプロパティが必要です。

  • 2つのオブジェクトが等しいと比較される場合、各オブジェクトのGetHashCodeメソッドは同じ値を返す必要があります。ただし、2つのオブジェクトが同等であると比較されない場合、2つのオブジェクトのGetHashCodeメソッドは異なる値を返す必要はありません。

  • オブジェクトのGetHashCodeメソッドは、オブジェクトのEqualsメソッドの戻り値を決定するオブジェクトの状態に変更がない限り、一貫して同じハッシュコードを返す必要があります。これはアプリケーションの現在の実行にのみ当てはまり、アプリケーションを再度実行すると別のハッシュコードが返される可能性があることに注意してください。

  • 最高のパフォーマンスを得るには、ハッシュ関数がすべての入力に対してランダムな分布を生成する必要があります。

C#コンパイラチームのEric Lippertは、GetHashCode彼のブログ(http://ericlippert.com/2011/02/28/guidelines-and-rules-for-gethashcode/ )で実装ルールの理論的根拠を説明しています。

于 2012-09-11T09:40:13.750 に答える
8

2 ^ 32の整数と無限の数の文字列しかないため、論理的に一意にGetHashCode することはできません(鳩の巣原理を参照)。


@Henkがコメントで指摘したように、文字列の数は無限ですが、s数は有限System.Stringです。ただし、鳩の巣原理は、後者が。よりもはるかに大きいため、依然として有効ですint.MaxValue

于 2012-09-11T09:42:59.717 に答える
2

各文字列のハッシュコードを文字列自体と一緒に保存すると、文字列のハッシュコードを「最初のステップ」として比較して、それらが等しいかどうかを比較できます。2つの文字列のハッシュコードが異なる場合、それらは等しくなく、1つは他に何もする必要はありません。同じ長さで、「ほぼ」であるが完全に等しくない文字列の多くのペアを比較することが予想される場合は、コンテンツをチェックする前にハッシュコードをチェックすると、パフォーマンスの最適化に役立つ場合があります。 2つの文字列のハッシュコードの計算は、それらを比較するよりもほぼ確実に遅いため、キャッシュされたハッシュコードがない場合、この「最適化」は価値がないことに注意してください。。ただし、他の目的でハッシュコードを計算してキャッシュする必要がある場合は、文字列を比較するための最初のステップとしてハッシュコードをチェックすると便利な場合があります。

于 2013-01-07T20:57:45.930 に答える
1

GetHashCode()を使用すると、限られた数のスペースInt32内で操作しているため、常に衝突のリスクがあります。これは、ハッシュアルゴリズムがこのスペース内で完全に分散されないという事実によっても悪化します。

HashTableまたはDictionaryの実装を見ると、GetHashCodeを使用してキーをバケットに割り当て、必要な比較の数を減らすことがわかります。ただし、同じバケットに複数のアイテムがある場合は、同等の比較が必要です。

于 2012-09-11T09:43:31.517 に答える
0

いいえ。GetHasCodeはハッシュコードを提供するだけです。衝突が発生します。異なるハッシュを持つことは文字列が異なることを意味しますが、同じハッシュを持つことは文字列が同じであることを意味しません。

GetHashCodeの正しい使用法については、EricLippertによるこれらのガイドラインを読んでください。

文字列を比較したい場合は、そうしてください!stringA == stringB正常に動作します。大きなセットで文字列が一意であることを確認する場合は、ハッシュコードの力を使用して、を使用しHashSet<string>ます。

于 2012-09-11T09:42:47.117 に答える