首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Java读取大文件的速度比C++快?

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

Stack Overflow用户
提问于 2014-04-09 15:04:17
回答 2查看 8.6K关注 0票数 54

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

代码语言:javascript
复制
apple
red
beautiful
smell
spark
input

我需要写一个程序来读取文件中的每个单词并打印单词计数。我用Java和C++写的,但结果令人惊讶: Java比C++快2.3倍。我的代码如下:

C++:

代码语言:javascript
复制
int main() {
    struct timespec ts, te;
    double cost;
    clock_gettime(CLOCK_REALTIME, &ts);

    ifstream fin("inputfile.txt");
    string word;
    int count = 0;
    while(fin >> word) {
        count++;
    }
    cout << count << endl;

    clock_gettime(CLOCK_REALTIME, &te);
    cost = te.tv_sec - ts.tv_sec + (double)(te.tv_nsec-ts.tv_nsec)/NANO;
    printf("Run time: %-15.10f s\n", cost);

    return 0;
}

输出:

代码语言:javascript
复制
5e+08
Run time: 69.311 s

Java:

代码语言:javascript
复制
 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");
}

输出:

代码语言:javascript
复制
5.0E8
Run time: 29 s

在这种情况下,为什么Java比C++快,如何提高C++的性能?

EN

回答 2

Stack Overflow用户

发布于 2014-04-09 16:39:49

这两种语言在处理I/O的方式上有许多显著的不同,所有这些都可以以某种方式产生不同。

也许第一个(也是最重要的)问题是:文本文件中的数据是如何编码的。如果它是单字节字符(ISO 8859-1UTF-8),那么Java必须在处理前将其转换为UTF-16;根据语言环境的不同,C++也可能(也可能不)转换或执行一些额外的检查。

正如已经指出的(至少是部分地),在C++中,>>使用特定于区域设置的isspacegetline将简单地与'\n'进行比较,后者可能更快。( isspace的典型实现将使用位图,这意味着每个字符都需要额外的内存访问。)

优化级别和特定库实现也可能有所不同。在C++中,一个库实现比另一个库快2到3倍并不少见。

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

票数 8
EN

Stack Overflow用户

发布于 2014-04-09 16:39:27

我怀疑主要的区别是java.io.BufferedReaderstd::ifstream性能更好,因为它有缓冲,而ifsteam不是。当您调用readLine()时,BufferedReader预先读取文件的大块,并将它们从内存传递给程序,而std::ifstream在您通过调用>>-operator提示它时,一次只读取几个字节。

从硬盘驱动器顺序访问大量数据通常比一次访问许多小块快得多。

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

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22955178

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档