ファイルから 2D 配列をロードしています。これは 15,000,000 * 3 int の大きさです (最終的には 40,000,000 * 3 になります)。今、私dataInputStream.readInt()
はintを順番に読んでいます。約 15 秒かかります。大幅に (少なくとも 3 倍) 速くすることはできますか?
質問する
674 次
2 に答える
7
ファイルをメモリにマップしてください!
Java 7 コード:
FileChannel channel = FileChannel.open(Paths.get("/path/to/file"),
StandardOpenOption.READ);
ByteBuffer buf = channel.map(0, channel.size(),
FileChannel.MapMode.READ_ONLY);
// use buf
詳しくはこちらをご覧ください。
Java 6 を使用する場合は、次のことを行う必要があります。
RandomAccessFile file = new RandomAccessFile("/path/to/file", "r");
FileChannel channel = file.getChannel();
// same thing to obtain buf
.asIntBuffer()
必要に応じて、バッファで使用することもできます。そして、読む必要があるときに、本当に読む必要のあるものだけを読むことができます。また、ヒープには影響しません。
于 2013-06-23T19:04:04.797 に答える
7
はい、できます。ファイルを読み取る13の異なる方法のベンチマークから:
最速のアプローチを選択する必要がある場合は、次のいずれかになります。
FileChannel
とMappedByteBuffer
配列の読み取りを使用します。FileChannel
直接ByteBuffer
読み取りと配列読み取りを使用します。FileChannel
ラップされた配列ByteBuffer
と直接配列アクセスを使用します。
最高の Java 読み取りパフォーマンスを得るには、次の 4 つの点に注意してください。
- 一度に 1 バイトではなく配列を読み取ることで、I/O 操作を最小限に抑えます。8 KB の配列が適切なサイズです (これが の既定値になっている理由です
BufferedInputStream
)。 - データを一度に 1 バイトではなく、一度に配列として取得することにより、メソッド呼び出しを最小限に抑えます。配列のインデックスを使用して、配列内のバイトを取得します。
- スレッド セーフが必要ない場合は、スレッド同期ロックを最小限に抑えます。スレッド セーフなクラスへのメソッド呼び出しを減らすか、 や などの非スレッド セーフなクラスを使用し
FileChannel
てMappedByteBuffer
ください。 - JVM/OS、内部バッファ、およびアプリケーション アレイ間のデータ コピーを最小限に抑えます。
FileChannel
メモリ マッピング、直接またはラップされた配列で使用しますByteBuffer
。
于 2013-06-23T19:06:49.173 に答える