複数のオブジェクトを含む、生成されたデータ ファイル (数百メガバイト) を処理していG
ます。これらのオブジェクトにランダム アクセスする必要があります。可能な実装は、大きなHashTable
. 私のプログラムはJavaで書かれており、これjava.util.HashMap
を処理できないようです(どういうわけか非常に遅いです)。これらのオブジェクトにランダムにアクセスするためのソリューションを推奨できる人はいますか?
3 に答える
aHashMap
が極端に遅い場合、次の 2 つの原因が考えられます。
キー クラスの
hashCode()
and/orequals(Object)
メソッドは非常に高価になる可能性があります。たとえば、配列またはコレクションをキーとして使用する場合、メソッドは呼び出すたびにすべての要素にアクセスし、メソッドhashCode()
は等しいキーに対して同じことを行います。equals
キー クラス
hashCode()
には、プログラムで使用される (個別の) キーのかなりの割合に対して同じ値を与える不適切なメソッドが含まれている可能性があります。これが発生すると、多くのキーの衝突が発生し、ハッシュ テーブルが大きくなるとパフォーマンスが大幅に低下する可能性があります。
データ構造を変更する前に、まずこれらの可能性を検討することをお勧めします。
注: 「いくつかの G オブジェクト」が数十億のオブジェクトを意味する場合、数百ギガバイトの RAM を備えたマシンでこのアプリケーションを実行していない限り、ファイルの内容をメモリに保持するのに問題があります。「封筒の裏側」の計算を行って、実行しようとしていることが実現可能かどうかを確認することをお勧めします。
キーが何であれ、 を介してそれぞれに適切なハッシュを生成していることを確認してくださいhashCode()
。多くの場合、HashMap のパフォーマンスが悪いのは、ハッシュの衝突が原因です。衝突が発生すると、HashMap は衝突するオブジェクトのリンク リストを生成します。
最悪の場合、すべてのオブジェクトに対して同じハッシュを返す場合、HashMap は本質的にリンクされたリストになります。ハッシュ関数を書くための良い出発点は次のとおりです: http://www.javamex.com/tutorials/collections/hash_function_guidelines.shtml
各オブジェクトが少しでない限り、数百MBは数十億のオブジェクトを保持できません(これは実際にはオブジェクトIMHOではありません)。
これにどのようにアプローチするかは、メモリ マップ ファイルを使用してデータの内容をマップし、別のメモリ マップ ファイルに独自のハッシュ テーブルを作成することです (キーを作成するためにデータを 1 回スキャンする必要があります)。
データのレイアウトによっては、ランダム アクセスがデータをキャッシュする最も効率的な方法ではないことを覚えておく価値があります。つまり、キャッシュには 64 バイトの行がロードされ (アーキテクチャによって異なります)、構造がメモリに収まらない場合は、レコード ベーステーブルの方が効率的かもしれません。