私は現在、JOGL(Java OpenGLバインディング)を使用して3Dグラフィックスアプリケーションを開発しています。簡単に言えば、私は巨大なランドスケープバイナリファイルを持っています。サイズが大きいため、実行時に地形チャンクをストリーミングする必要があります。したがって、ランダムアクセスの懸念が明確にわかります。私はすでに最初の(そして汚い:))実装を完了しました(おそらくそれはマルチスレッドです)、そこで私は愚かなアプローチを使用しています...これがその初期化です:
dataInputStream = new DataInputStream(new BufferedInputStream(fileInputStream,4 * 1024);
dataInputStream.mark(dataInputStream.available());
そして、特別なチャンクを読み取る(ストリーミングする)必要がある場合(ファイル内の「オフセット」はすでにわかっています)、次のことを実行しています(恥ずかしいです:)):
dataInputStream.reset();
dataInputStream.skipBytes(offset);
dataInputStream.read(whatever I need...);
私はほとんど経験がなかったので、最初に考えることができました:)それで、これまでに3つの有用で非常に興味深い記事を読みました(おそらくこのトピックに興味があるなら、それらを読むことをお勧めします)
バイトバッファと非ヒープメモリ-グレゴリー氏はJavaNIOに精通しているようです。
Javaのヒント:ファイルをすばやく読み取る方法[http://nadeausoftware.com/articles/2008/02/java_tip_how_read_files_quickly]-これは興味深いベンチマークです。
記事:Java I /Oパフォーマンスの調整[http://java.sun.com/developer/technicalArticles/Programming/PerfTuning/]-Sunの簡単な推奨事項ですが、下にスクロールして、そこにある「ランダムアクセス」セクションを参照してください。これらは、自己バッファリングが改善されたRandomAccessFile(RAF)の単純な実装を示しています。
グレゴリー氏は、彼の記事の最後にいくつかの*.javaファイルを提供しています。それらの1つは、FileChannel + ByteBuffer + Mapping(FBM)とRAFの間のベンチマークです。彼は、RAFと比較してFBMを使用すると4倍のスピードアップに気づいたと言います。このベンチマークは、次の条件で実行しました。
- オフセット(アクセス場所など)はランダムに生成されます(ファイルスコープでは、0-file.length()など)。
- ファイルサイズは220MBです。
- 1 000 000アクセス(75%の読み取りと25%の書き込み)
結果は驚くべきものでした:
RAFの場合は約28秒! FBMの場合は約0.2秒!
ただし、このベンチマークでの彼のRAFの実装には自己バッファリングがありません(3番目の記事で自己バッファリングについて説明しています)。したがって、パフォーマンスを大幅に低下させるのは「RandomAccessFile.seek」メソッド呼び出しだと思います。
さて、私が学んだすべてのことの後に、1つの質問と1つのジレンマがあります:)
質問:「FileChannel.map」を使用してファイルをマッピングする場合、Javaはファイルの内容全体をMappedByteBufferにコピーしますか?それともそれをエミュレートするだけですか?コピーする場合、FBMアプローチを使用することは私の状況には適していませんか?
ジレンマ:質問に対するあなたの答えに依存します...
マッピングがファイルをコピーする場合、2つの解決策しか考えられないようです:RAF +セルフバッファリング(3番目の記事からのもの)またはFileChannelの位置を利用する(マッピングではない)...どちらになりますか良くなる?
マッピングでファイルがコピーされない場合は、3つのオプションがあります。前の2つのオプションとFBM自体です。
編集:ここにもう1つの質問があります。ここにいる人の中には、マッピングはファイルをMappedByteBufferにコピーしないと言う人もいます。では、なぜ1GBのファイルをマップできないのですか、「マップに失敗しました」というメッセージが表示されます...
PSインターネットでこのトピックに関する一貫した情報を見つけることができないので、アドバイス付きの充実した回答を受け取りたいと思います。
ありがとう :)