組み込み Linux デバイスで Java 1.5 を使用しており、2MB の int 値を含むバイナリ ファイルを読みたいと考えています。(現在は 4 バイトのビッグ エンディアンですが、フォーマットは私が決めることができます)
DataInputStream
via using ) をBufferedInputStream
使用するdis.readInt()
と、これらの 500 000 の呼び出しを読み取るには 17 秒が必要ですが、1 つの大きなバイト バッファーに読み取られるファイルには 5 秒かかります。
そのファイルを 1 つの巨大な int[] にすばやく読み込むにはどうすればよいですか?
読み取りプロセスでは、さらに 512 kb を超えて使用しないでください。
以下のコードnio
は、Java io の readInt() アプローチよりも高速ではありません。
// asume I already know that there are now 500 000 int to read:
int numInts = 500000;
// here I want the result into
int[] result = new int[numInts];
int cnt = 0;
RandomAccessFile aFile = new RandomAccessFile("filename", "r");
FileChannel inChannel = aFile.getChannel();
ByteBuffer buf = ByteBuffer.allocate(512 * 1024);
int bytesRead = inChannel.read(buf); //read into buffer.
while (bytesRead != -1) {
buf.flip(); //make buffer ready for get()
while(buf.hasRemaining() && cnt < numInts){
// probably slow here since called 500 000 times
result[cnt] = buf.getInt();
cnt++;
}
buf.clear(); //make buffer ready for writing
bytesRead = inChannel.read(buf);
}
aFile.close();
inChannel.close();
更新: 回答の評価:
PC では、IntBuffer アプローチを使用したメモリ マップが私の設定で最速でした。
組み込みデバイスでは、jit を使用しない場合、java.io DataiInputStream.readInt() は少し高速でした (17 秒、IntBuffer を使用した MemMap では 20 秒)。
最終的な結論: 大幅な高速化は、アルゴリズムの変更により実現しやすくなります。(初期化用の小さいファイル)