4

ファイルから 2D 配列をロードしています。これは 15,000,000 * 3 int の大きさです (最終的には 40,000,000 * 3 になります)。今、私dataInputStream.readInt()はintを順番に読んでいます。約 15 秒かかります。大幅に (少なくとも 3 倍) 速くすることはできますか?

4

2 に答える 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の異なる方法のベンチマークから:

最速のアプローチを選択する必要がある場合は、次のいずれかになります。

  • FileChannelMappedByteBuffer配列の読み取りを使用します。
  • FileChannel直接ByteBuffer読み取りと配列読み取りを使用します。
  • FileChannelラップされた配列ByteBufferと直接配列アクセスを使用します。

最高の Java 読み取りパフォーマンスを得るには、次の 4 つの点に注意してください。

  • 一度に 1 バイトではなく配列を読み取ることで、I/O 操作を最小限に抑えます。8 KB の配列が適切なサイズです (これが の既定値になっている理由です BufferedInputStream)。
  • データを一度に 1 バイトではなく、一度に配列として取得することにより、メソッド呼び出しを最小限に抑えます。配列のインデックスを使用して、配列内のバイトを取得します。
  • スレッド セーフが必要ない場合は、スレッド同期ロックを最小限に抑えます。スレッド セーフなクラスへのメソッド呼び出しを減らすか、 や などの非スレッド セーフなクラスを使用しFileChannelMappedByteBufferください。
  • JVM/OS、内部バッファ、およびアプリケーション アレイ間のデータ コピーを最小限に抑えます。FileChannelメモリ マッピング、直接またはラップされた配列で使用しますByteBuffer
于 2013-06-23T19:06:49.173 に答える