Javaで大きなファイルを一行ずつ読み書きをする最速の方法
限られたメモリ(約64MB)の中で、Javaで大きなファイル(0.5~1GB)を読み書きする最速の方法をいろいろと探しています。ファイルの各行はレコードを表すので、私はそれらを行ごとに取得する必要があります。ファイルは通常のテキストファイルです。
BufferedReaderやBufferedWriterを試しましたが、どうもベストな選択とは思えません。サイズ0.5GBのファイルを、何も処理せずに読み書きのみで、約35秒かかっています。読み込みだけでも10秒程度かかるので、ここでのボトルネックは書き込みだと思います。
バイトの配列を読み込もうとしましたが、そうすると読み込んだ各配列の行を検索するのに時間がかかります。
何かご提案があればお願いします。 ありがとうございます。
19
3
あなたの本当の問題は、ハードウェアが限られていて、ソフトウェアで何をやってもあまり変わらないことなのではないでしょうか。メモリやCPUに余裕があれば、より高度なトリックが有効ですが、ファイルがキャッシュされていないためにハードディスクで待機しているだけなら、あまり大きな違いはありません。
ちなみに、10秒で500MB、50MB/secは、HDDの一般的な読み込み速度です。
どの時点でシステムが効率的にファイルをキャッシュできなくなるかを確認するために、以下を実行してみてください。
メモリがたくさんあるLinuxマシンで
Windowsマシンで、メモリを多く搭載している場合。
まず試してみたいのは、BufferedReaderとBufferedWriterのバッファサイズを大きくすることです。デフォルトのバッファサイズは文書化されていませんが、少なくともOracle VMでは8192文字で、これはあまりパフォーマンス上の利点をもたらさないでしょう。
もし、ファイルのコピーを取るだけなら(そして、データへの実際のアクセスは必要ない)、私なら、リーダー/ライター方式をやめて、バッファとしてバイト配列を使ったInputStreamとOutputStreamで直接作業します。
または実際にNIOを使用します。
しかし、異なるコピー方式をベンチマークした場合、実装の違いよりもベンチマークの実行ごとの差(時間)の方がはるかに大きくなりました。ここでは、I/Oキャッシュ(OSレベルとハードディスクキャッシュの両方)が大きな役割を果たし、何が速いかを言うのは非常に難しい。私のハードウェアでは、BufferedReaderとBufferedWriterを使用して1GBのテキストファイルを1行ずつコピーすると、ある実行では5秒未満、別の実行では30秒以上かかっています。
私は、
java.nio
パッケージのクラスを見ることをお勧めします。 ソケットの場合、ノンブロッキングIOの方が速いかもしれません。http://docs.oracle.com/javase/6/docs/api/java/nio/package-summary.html
この記事には、それが真実であるとするベンチマークがあります'。
http://vanillajava.blogspot.com/2010/07/java-nio-is-faster-than-java-io-for.html