我正在从文件中加载一个 2D 数组,它有 15,000,000 * 3 ints 大(最终将是 40,000,000 * 3)。现在,我使用dataInputStream.readInt()
顺序读取整数。大约需要 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
用 aMappedByteBuffer
和数组读取。FileChannel
直接ByteBuffer
和数组读取。FileChannel
使用包装数组ByteBuffer
和直接数组访问。
为了获得最佳的 Java 读取性能,需要记住 4 件事:
- 通过一次读取一个数组而不是一次读取一个字节来最小化 I/O 操作。8 KB 数组是一个很好的大小(这就是为什么它是 的默认值
BufferedInputStream
)。 - 通过一次获取一个数组而不是一次获取一个字节来最小化方法调用。使用数组索引来获取数组中的字节。
- 如果您不需要线程安全,请尽量减少线程同步锁。要么减少对线程安全类的方法调用,要么使用非线程安全类,如
FileChannel
andMappedByteBuffer
。 - 最大限度地减少 JVM/OS、内部缓冲区和应用程序阵列之间的数据复制。
FileChannel
与内存映射或直接或包装数组一起使用ByteBuffer
。
于 2013-06-23T19:06:49.173 回答