4

我正在从文件中加载一个 2D 数组,它有 15,000,000 * 3 ints 大(最终将是 40,000,000 * 3)。现在,我使用dataInputStream.readInt()顺序读取整数。大约需要 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 种不同读取文件方式的基准测试

如果您必须选择最快的方法,它将是以下方法之一:

  • FileChannel用 aMappedByteBuffer和数组读取。
  • FileChannel直接ByteBuffer和数组读取。
  • FileChannel使用包装数组ByteBuffer和直接数组访问。

为了获得最佳的 Java 读取性能,需要记住 4 件事:

  • 通过一次读取一个数组而不是一次读取一个字节来最小化 I/O 操作。8 KB 数组是一个很好的大小(这就是为什么它是 的默认值 BufferedInputStream)。
  • 通过一次获取一个数组而不是一次获取一个字节来最小化方法调用。使用数组索引来获取数组中的字节。
  • 如果您不需要线程安全,请尽量减少线程同步锁。要么减少对线程安全类的方法调用,要么使用非线程安全类,如FileChanneland MappedByteBuffer
  • 最大限度地减少 JVM/OS、内部缓冲区和应用程序阵列之间的数据复制。FileChannel与内存映射或直接或包装数组一起使用ByteBuffer
于 2013-06-23T19:06:49.173 回答