这是为什么;“行计数”;Java编程速度慢?使用MappedByteBuffer
为了尝试这是为什么;“行计数”;Java编程速度慢?使用MappedByteBuffer,java,performance,nio,mappedbytebuffer,Java,Performance,Nio,Mappedbytebuffer,为了尝试MappedByteBuffer(Java内存映射文件),我编写了一个简单的wc-l(文本文件行数)演示: int-wordCount(字符串文件名)引发IOException{ FileChannel fc=new RandomAccessFile(新文件名),“r”).getChannel(); MappedByteBuffer mem=fc.map(FileChannel.MapMode.READ_ONLY,0,fc.size()); int-nlines=0; 字节换行符='\n
MappedByteBuffer
(Java内存映射文件),我编写了一个简单的wc-l
(文本文件行数)演示:
int-wordCount(字符串文件名)引发IOException{
FileChannel fc=new RandomAccessFile(新文件名),“r”).getChannel();
MappedByteBuffer mem=fc.map(FileChannel.MapMode.READ_ONLY,0,fc.size());
int-nlines=0;
字节换行符='\n';
用于(长i=0;i
我在一个大约15MB(15008641字节)和100k行的文件上尝试了这个方法。在我的笔记本电脑上,大约需要13.8秒。为什么这么慢
完整的课程代码如下:
作为参考,我用C写了同样的想法:
它的运行时间约为28毫秒,比以前快了490倍
出于好奇,我还使用与Java中基本相同的算法和API编写了一个Scala版本。它的运行速度是的10倍
,这表明确实发生了一些奇怪的事情
更新:文件由操作系统缓存,因此不需要磁盘加载时间
我想使用内存映射来随机访问可能不适合RAM的较大文件。这就是为什么我不只是使用BufferedReader。代码非常慢,因为
fc.size()
是在循环中调用的
JVM显然无法消除fc.size()
,因为文件大小可以在运行时更改。查询文件大小相对较慢,因为它需要对底层文件系统进行系统调用
将此更改为
long size = fc.size();
for (long i = 0; i < size; i++) {
...
}
long size=fc.size();
用于(长i=0;i
Java版本:OpenJDK 1.8.0平台:Linux 4.1.16MappedByteBuffer
使用错误,您的程序只需要一个普通的BufferedReader
。您没有使用MappedByteBuffer
的任何高级功能,那么为什么要使用它呢?我正在键入答案,但问题已解决。您的代码很慢,因为它逐字节读取,这非常慢。一个接一个地读取缓冲区,性能将显著提高。使用,例如,花费的时间是50493us。对8646279us。对于您的原始版本。但我同意BufferedInputStream无论如何都会更简单。@JarrodRoberson谢谢你的指针!该文件由操作系统缓存,我将更新该问题。我想使用内存映射随机访问可能不适合RAM的较大文件。@JarrodRoberson你认为重新打开该文件合理吗,因为我不相信你标记的问题提供了答案?哈哈,我完全错了。这就是原因。哎哟!一定是很愚蠢的事情。谢谢现在运行时间为73毫秒,比C性能低2.6倍。@cidermole包括JVM启动?@tagir valeev不包括JVM启动
long size = fc.size();
for (long i = 0; i < size; i++) {
...
}