09/09/03 06:40:43
もし>>174の通りfloatデータが16GB分あるのならデータ個数はintの範囲を超えるので、
たとえメモリが潤沢にあったとしてもデータ全体を収めるfloatの配列を作ることはできない。
また物理メモリサイズと同程度の大きさを確保してデータを収めるために使えば、
JVMやOSその他で使っているメモリが追いやられてしまうので速度的にとても不利になる。
もう少し小さめの例えば4GBくらいのfloat配列を確保して、
(1) 4GB分データをfloat配列に読み込む。
(2) float配列をソートする。クイックソートを使うArrays#sortでもいいし、他の好みのソートでもいいと思う。
(3) ソートされた配列の内容を一時ファイルに書き出す。
(4) (1)-(3)を4回繰り返して4つの一時ファイルを作成する。
ここまでが部分ごとにソートされたデータを作成する段階で、
(5) 1番目と2番目、3番目と4番目に作成した一時ファイルをそれぞれマージして新たなファイルを2個作成する。
(6) (5)で作成した2個のファイルをマージして全体がソートされた出力ファイルとする。
のように2つのファイルの先頭から小さい方(大きい方)を取り出して新しいファイルに出力することを繰り返す。
もちろんファイルの読み書きでは1個ずつとかでなくバッファを利用した読み書きにする。
FileChannelを利用し、バッファも大きいサイズのダイレクトバッファを予め用意して使い回せば、
ファイルの読み書きは少しは速くなるかもしれない。
ディスクの空き容量がそれなりに必要(上の例なら元データ+ソート済みデータ+2段階の一時ファイルで64GB分)なので、
空き容量次第で一時ファイルはマージ終了後にすぐに消さないといけないかもしれない。
それからJVMの最大ヒープサイズの初期設定は物理メモリの1/4か1GBの小さい方なので-Xmxで必要分を指定してやること。
初期ヒープサイズもついでに最初から大きく取っておいてもいいかも。