从文件加载大型2D int数组的最快方法是什么?

时间:2013-06-23 18:55:08

标签: java performance

我正在从文件中加载一个2D数组,它是15,000,000 * 3整数(最终将是40,000,000 * 3)。现在,我使用dataInputStream.readInt()来顺序读取整数。大约需要15秒。我可以使它显着(至少3倍)更快,或者这个速度和我一样快吗?

2 个答案:

答案 0 :(得分: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

有关详细信息,请参阅here

如果您使用Java 6,则必须:

RandomAccessFile file = new RandomAccessFile("/path/to/file", "r");
FileChannel channel = file.getChannel();
// same thing to obtain buf

如果需要,您甚至可以在缓冲区上使用.asIntBuffer()。当您需要阅读时,您只能阅读实际需要阅读的内容。 它不会影响你的堆。

答案 1 :(得分:7)

是的,你可以。来自benchmark of 13 different ways of reading files

如果你必须选择最快的方法,那就是其中之一:

  • FileChannelMappedByteBuffer,数组读取。
  • FileChannel使用直接ByteBuffer并且数组读取。
  • FileChannel包含数组ByteBuffer和直接数组访问。

为了获得最佳的Java读取性能,需要记住以下四点:

  • 通过一次读取一个数组来最小化I / O操作,而不是一个字节 一段时间。 8 KB数组的大小合适(这就是BufferedInputStream的默认值)。
  • 通过一次获取数据一个数组而不是一个字节来最小化方法调用 一次。使用数组索引来获取数组中的字节数。
  • 如果不需要线程,请最小化线程同步锁 安全。要么对线程安全类进行较少的方法调用,要么使用 一个非线程安全的类,如FileChannelMappedByteBuffer
  • 最大限度地减少JVM / OS,内部缓冲区和内部缓冲区之间的数据复制 应用程序数组。使用带有内存映射的FileChannel或直接映射 或包裹数组ByteBuffer