Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
这是为什么;“行计数”;Java编程速度慢?使用MappedByteBuffer_Java_Performance_Nio_Mappedbytebuffer - Fatal编程技术网

这是为什么;“行计数”;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.16
MappedByteBuffer
使用错误,您的程序只需要一个普通的
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++) {
        ...
    }