缓冲输入与标准输入

时间:2014-07-24 07:23:54

标签: c++ io buffer

我试图从输入文件中读取一长串数字(大约10 ^ 7)。通过一些搜索,我发现使用缓冲区读取内容与逐个读取数字相比具有更高的性能。

我的第二个程序比第一个程序表现更好。我在第一个程序中使用cin流对象,在第二个程序中使用stringstream对象。这两者在I / O性能方面有什么区别?

#include <iostream>
using namespace std;

int main()
{
    int n,k;
    cin >> n >> k;
    int count = 0;
    while ( n-- > 0 )
    {
        int num;
        cin >> num;
        if( num % k == 0 )
            count++;
    }
    cout << count << endl;
    return 0;
}

与使用缓冲输入的以下代码相比,此程序花费的时间更长。

#include <iostream>
#include <sstream>
using namespace std;

int main()
{
    cin.seekg(0, cin.end);
    int length = cin.tellg();
    cin.seekg(0, cin.beg);
    char *buffer = new char[length];
    cin.read(buffer,length);
    stringstream ss(buffer);
    int n,k;
    ss >> n >> k;
    int result = 0;
    while( n-- )
    {
        int num;
        ss >> num;
        if( num % k == 0 )
            result++;
    }
    cout << result << endl;
    return 0;
}

1 个答案:

答案 0 :(得分:2)

第二个将需要内存中文件大小的两倍〜,否则,因为它在一次调用中读取整个文件,它可能会像底层存储器一样快地将数据读入内存,并且然后以CPU的速度处理它。

避免内存成本会很好,在这方面,您的第一个程序会更好。在我的系统上,使用名为test.txt的输入,如下所示:

10000000 2
13
13
< 10000000-2 more "13"s. >

并且您的第一个程序名为a,第二个程序名为b。我明白了:

% time ./a <test.txt 
0
./a < test.txt  1.70s user 0.01s system 99% cpu 1.709 total
% time ./b <test.txt
0
./b < test.txt  0.76s user 0.04s system 100% cpu 0.806 total

cin默认情况下不缓冲,以保持&#34;同步&#34;与stdio。有关详细说明,请参阅this excellent answer。为了使其缓冲,我将cin.sync_with_stdio(false)添加到您的第一个程序的顶部,并调用结果c,其运行速度可能稍快一些:

% time ./c <test.txt
0
./c < test.txt  0.72s user 0.01s system 100% cpu 0.722 total

(注意:时间稍微松了一点,我只进行了一些测试,但c似乎至少和b一样快。)

你的第二个程序运行得很快,因为虽然没有缓冲,但我们只能发出一个读取调用。第一个程序必须为每个cin >>发出一个读取调用,而第三个程序可以缓冲(每隔一段时间发出一次读取调用)。

请注意,添加此行意味着您无法使用该名称使用C stdinFILE *读取,或调用任何可执行此操作的库方法。在实践中,这可能不是问题。