为什么Java读取大文件的速度比C++;?

为什么Java读取大文件的速度比C++;?,java,c++,file,Java,C++,File,我有一个2GB文件(iputfile.txt),文件中的每一行都是一个单词,就像: apple red beautiful smell spark input 我需要写一个程序来读取文件中的每个单词并打印单词数。我用java和C++编写了它,但是结果令人惊讶:java运行的速度比C++快2.3倍。我的代码如下: C++: 爪哇: 输出: 5e+08 Run time: 69.311 s 5.0E8 Run time: 29 s 为什么在这种情况下java比C++更快,我如何提高C++的性能

我有一个2GB文件(
iputfile.txt
),文件中的每一行都是一个单词,就像:

apple
red
beautiful
smell
spark
input
我需要写一个程序来读取文件中的每个单词并打印单词数。我用java和C++编写了它,但是结果令人惊讶:java运行的速度比C++快2.3倍。我的代码如下:

C++:

爪哇:

输出:

5e+08
Run time: 69.311 s
5.0E8
Run time: 29 s

<>为什么在这种情况下java比C++更快,我如何提高C++的性能?

< p>你没有比较相同的东西。java程序读取行,在换行符上加上,而C++程序读取空白分隔的“单词”,这是一个额外的工作。 尝试
istream::getline

以后

您还可以尝试执行基本读取操作来读取字节数组并扫描该数组以查找换行符

甚至以后

在我的旧Linux笔记本上,JDK1.7.0S21和DoT-Tel-ME-IT的老版本4.3.3都是同时使用的,与C++ GETLINE相比。(我们已经确定读单词的速度较慢。)考虑到循环中代码的简单性,-O0和-O2之间没有太大区别,这一点我并不感到惊讶

最后一个音符
正如我所建议的,FIN。Lead(缓冲区,LeN)用LeN= 1MB,使用MyCHR扫描‘n’,导致另一个速度提高了大约20%,这使得C(现在没有任何C++)比java快。

< P>我不是C++专家,但是至少有以下影响性能:

  • 文件的操作系统级缓存
  • 对于Java,您使用的是缓冲读取器,缓冲区大小默认为页面或其他内容。我不确定C++流是如何做到这一点的。
  • <> LI>因为文件太大,JIT可能会被踢入,它可能比你不为C++编译器打开任何优化时编译java字节代码更好。
    由于成本是这里的主要成本,我想1和2是主要原因。

    我怀疑主要区别在于
    java.io.BufferedReader
    std::ifstream
    性能更好,因为它具有缓冲功能,而ifstream则没有。当您调用
    readLine()
    时,BufferedReader预先读取文件的大块,并将它们从RAM中传递给您的程序,而当您通过调用
    >
    -运算符提示时,std::ifstream一次只读取几个字节

    从硬盘顺序访问大量数据通常比一次访问多个小块要快得多


    更公平的比较是将std::ifstream与未缓冲的java.io.FileReader进行比较

    语言处理,所有这些都可以通过一种方式产生影响 或者别的

    也许第一个(也是最重要的)问题是:经济状况如何 在文本文件中编码的数据。如果是单字节字符 (或),然后Java必须将其转换为 加工前;根据区域设置,C++可以(或不可以) 还要转换或执行一些附加检查

    已指出(至少部分),在C++中,<>代码> > /COD>使用 特定于语言环境的

    isspace
    getline
    只需比较
    “\n”
    ,这可能更快。(典型的
    isspace
    将使用位图,这意味着额外的内存 每个字符的访问权限。)

    优化级别和特定的库实现可能会 也各不相同。C++在一个图书馆中并不罕见。 实现速度要比另一个快2到3倍

    最后,一个最显著的区别:C++区别 在文本文件和二进制文件之间。您已在中打开该文件 文本模式;这意味着它将在 最低级别,甚至在提取操作员看到它之前。这 取决于平台:对于Unix平台,“预处理” 是不可操作的;在Windows上,它将CRLF对转换为
    '\n'
    , 这将对性能产生一定的影响。如果我记得的话 正确地说(我已经好几年没有使用Java了),Java期望 更高级别的函数来处理这个问题,所以
    readLine
    将稍微复杂一些。只是猜测 在这里,但我怀疑在更高的 级别在运行时的成本低于级别的缓冲区预处理 下层。(如果您在Windows下进行测试,您可能会 在C++中用二进制模式打开文件的实验。 当发生错误时,程序的行为应该没有区别 您使用
    >
    ;任何额外的CR都将被视为空白。使用
    getline
    ,您必须添加逻辑以删除任何尾随
    '\r'
    到您的代码中。)

    我也会尝试使用,而不是标准的文件读/写。这样,当应用程序只关心数据时,操作系统就可以处理读写操作

    没有任何情况下,C++不能比java快,但是有时需要非常有才华的人做大量的工作。但我不认为这项任务太难击败,因为这是一项直截了当的任务


    Windows的MMAP描述在().< /P>运行C++版本,然后是java版本,然后C++版本再次。这可能会捕获系统缓存。(但是,即使是磁盘I/O,69秒也相当长)。而且,你是否已经编译了(或)没有优化(-O)打开?@ USE3513917 C++ + STL实现通常在使用没有编译器优化(如内联)时表现不佳。您甚至不应该查看关闭优化的C++程序的性能;一个细节:C++没有自动初始化变量计数为零。我并不太惊讶java比C++ iFix流有点快。iostreams设计受到面向对象和使用虚拟函数的影响。与java虚拟机不同,C++无法将虚拟调用转换为内联调用。你会好起来的

     public static void main(String[] args) throws Exception {
    
        long startTime = System.currentTimeMillis();
    
        FileReader reader = new FileReader("inputfile.txt");
        BufferedReader br = new BufferedReader(reader);
        String str = null;
        int count = 0;
        while((str = br.readLine()) != null) {
            count++;
        }
        System.out.println(count);
    
        long endTime = System.currentTimeMillis();
        System.out.println("Run time : " + (endTime - startTime)/1000 + "s");
    }
    
    5.0E8
    Run time: 29 s