バケットの数を設定し、それらの間にオブジェクトをできるだけ均等に分散させることが重要なのはなぜですか?
AHashSet
は、平均してO(1)時間のメンバーシップを判別できる必要があります。ドキュメントから:
このクラスは、ハッシュ関数が要素をバケット間で適切に分散することを前提として、基本操作(追加、削除、包含、およびサイズ設定)に対して一定時間のパフォーマンスを提供します。
これを実現するためにaが使用するアルゴリズムはHashset
、オブジェクトのハッシュコードを取得し、これを使用して正しいバケットを見つけることです。次に、等しいアイテムが見つかるまで、バケット内のすべてのアイテムを繰り返し処理します。バケット内のアイテムの数がO(1)より大きい場合、ルックアップにはO(1)時間より長くかかります。
最悪の場合(すべてのアイテムが同じバケットにハッシュされる場合)、オブジェクトがセットに含まれているかどうかを判断するのにO(n)時間がかかります。
バケットに対するオブジェクトの理想的な比率は何でしょうか?
ここには時空のトレードオフがあります。バケットの数を増やすと、衝突の可能性が低くなります。ただし、メモリ要件も増加します。ハッシュセットには2つのパラメーターがinitialCapacity
あり、作成するloadFactor
バケットの数を調整できHashSet
ます。デフォルトの負荷率は0.75で、これはほとんどの目的で問題ありませんが、特別な要件がある場合は、別の値を選択できます。
これらのパラメータの詳細については、次のドキュメントを参照してHashMap
ください。
この実装は、ハッシュ関数が要素をバケット間で適切に分散させることを前提として、基本操作(getおよびput)に一定時間のパフォーマンスを提供します。コレクションビューの反復には、HashMapインスタンスの「容量」(バケットの数)とそのサイズ(キーと値のマッピングの数)に比例する時間が必要です。したがって、反復パフォーマンスが重要な場合は、初期容量を高く設定しすぎない(または負荷率を低く設定しすぎない)ことが非常に重要です。
HashMapのインスタンスには、そのパフォーマンスに影響を与える2つのパラメーターがあります。初期容量と負荷率です。容量はハッシュテーブル内のバケットの数であり、初期容量は単にハッシュテーブルが作成されたときの容量です。負荷率は、容量が自動的に増加する前にハッシュテーブルがどれだけいっぱいになるかを示す尺度です。ハッシュテーブルのエントリ数が負荷率と現在の容量の積を超える場合、rehashメソッドを呼び出すことで容量が約2倍になります。
原則として、デフォルトの負荷率(.75)は、時間とスペースのコストの間の適切なトレードオフを提供します。値を大きくすると、スペースオーバーヘッドは減少しますが、ルックアップコストが増加します(getおよびputを含むHashMapクラスのほとんどの操作に反映されます)。再ハッシュ操作の数を最小限に抑えるために、初期容量を設定するときに、マップ内の予想されるエントリ数とその負荷率を考慮する必要があります。初期容量が最大エントリ数を負荷率で割った値よりも大きい場合、再ハッシュ操作は発生しません。