文字列の不変性の利点の1つは、アクセスを高速化するためのハッシュコードキャッシングです。
- この場合、同じハッシュコードを持つ文字列のキャッシュはどのように処理されますか?
- この場合、本当にパフォーマンスが向上しますか?
この場合、同じハッシュコードを持つ文字列のキャッシュはどのように処理されますか?
キャッシュされるのは文字列のハッシュコードです。int
文字列自体のプライベートフィールドにキャッシュされます。ハッシュコードはそれぞれのStringオブジェクトに格納されているため、異なる文字列が同じハッシュコードを持っている場合でも違いはありません。
(最も重要なことは、文字のシーケンスが同じである(したがって、であるequal
)2つの文字列が同じハッシュコード値を持っていることです。Java文字列のハッシュコードアルゴリズムが標準化されているため、これが保証されます...そしてこのプロパティがあります。)
この場合、本当にパフォーマンスが向上しますか?
平均して、はい、そして文字列の長さが長くなるにつれてそれ以上になります。
適切な文字列ハッシュコードアルゴリズムは、文字列内のすべての文字を調べる必要があります...そうしないと、同様の文字列が同じハッシュコードに体系的にマッピングされる可能性があります(つまり、BADです)。それらのN文字を何度も見ないようにすることは大きな勝利です。
キャッシングが役に立たない唯一の重要なケースは次のとおりです。
(もう1つの非常にあいまいなケースがあります。String
ハッシュする場合0
、キャッシュは無効になります。これは、String
クラス0
がキャッシュフィールドでハッシュコードがキャッシュされていないことを示すために使用するためです。)
この場合、同じハッシュコードを持つ文字列のキャッシュはどのように処理されますか?
あなたの質問の最初の部分がわかりません。キャッシュは、ハッシュコードが同じであるかどうかに関係なく、すべての文字列に対して同じように処理されます(2つの異なる文字列は理論的に同じhashCodeを持つことができるため、hashCodesが等しい場合、文字列が等しいことを意味するわけではありません)。ただし、同じStringオブジェクトが使用されている場合は、hashCodeがキャッシュされるため、再計算する必要はありません。
それは本当にパフォーマンスを向上させますか?
明確にはい
キャッシュは、Stringオブジェクト内の単なるintフィールドです。複数の文字列が問題なく同じハッシュコードを持つことができます。
次の理由により、パフォーマンスが大幅に向上します。
興味がある場合は、ソースを確認する価値があります。
ほとんどの場合、文字列をHashMapに配置しようとするまで、hashCodeは計算されません。次に、マップはそれをMap.Entryにキャッシュして、比較と再ハッシュを高速化します。
最初のものについては、それはあなたのハッシュ戦略に依存します。たとえば、ある単語の文字のすべてのASCIIコードをこの文字のハッシュコード(aの場合は65、Aの場合は97)に追加すると、この状況では、単語「abc」と「bca」のハッシュコードは同じになります。
2つ目は、ハッシュ戦略にもよりますが、ほとんどの場合、答えは「はい」です。