c ++ cout重定向到文件比使用ofstream慢

yig*_*alk 2 c++ cout ostream

我有一个应用程序,必须遍历每个字符(以检查某些特殊情况),然后使用ostream put方法将其写入流中。

当将ostream *指向文件流时,它的执行速度比ostream *指向重定向到文件的cout时快得多。

在这个(/sf/answers/118853451/)答案中,我看到使用fstream的可能会更快,因为与cout相比,缓冲多了一层。我以为,当我知道输出将要输出到cout时,我可以遍历字符串缓冲区,当缓冲区已满时,将其附加到cout。这样,我可以获得另一层缓冲,性能将会提高。

因此,我在这里进行了测试,以编写3200万行,每行是一个十个字符的字符串。我使用cout,fstream和stringbuffer编写它们,后来将它们附加到cout。


void print_to_ostream(ostream *out, string& ones)
{
    for (int i = 0; i < 32000000; ++i){

            const char* ones_char = ones.c_str();
            for (int j = 0; j < ones.size(); ++j ){
                out->put(ones_char[j]);
            }
        }
}

int main(void){
    string ones ="1111111111";


    ostream *out = &cout;
    size_t cout_time = 0;
    size_t file_time = 0;
    size_t cout_buffered_time = 0;

    // print cout using ostream
    mono_tick_timer time;
    print_to_ostream(out, ones);
    cout_time += time.tick();

    // write to file using ostream
    ofstream file("/tmp/test_file");
    out = &file;
    time.tick();
    print_to_ostream(out, ones);
    file_time += time.tick();

    // ***optional solution***
    // print to cout but passing through a string buffer
    stringstream buffer;
    out = &buffer;

    time.tick();
    print_to_ostream(out, ones);
    cout_buffered_time += time.tick();
    cout << buffer.str();
    size_t buf_to_cout = time.tick();


    std::cerr << "cout time: " <<  (double)cout_time / 1e6 << endl;
    std::cerr << "file time: " <<  (double)file_time / 1e6 << endl;
    std::cerr << "cout buffered time: " <<  (double)cout_buffered_time / 1e6 << endl;
    std::cerr << "buf_to_cout: " <<  (double)buf_to_cout / 1e6 << endl;

    return 0;

}

Run Code Online (Sandbox Code Playgroud)

运行的结果./a.out > /tmp/test_times 如下(毫秒):

cout time: 4773.62
file time: 2391.52
cout buffered time: 2380.83
buf_to_cout: 131.615
Run Code Online (Sandbox Code Playgroud)

我的底线问题是:在将所有内容附加到cout之前使用stringstream作为缓冲区是一个好的解决方案吗?考虑到以下事实:有时cout会以较大的输出重定向到文件,有时只是将其打印到控制台?

它们是否有我在使用此解决方案时没有想到的负面影响?还是有我没想到的更好的一个?

Max*_*kin 6

全局流(例如std::cout)是sync_with_stdio默认设置,而std::ofstream不是:

默认情况下,所有八个标准C ++流均与其各自的C流同步。

如果关闭同步,则允许C ++标准流独立地缓冲其I / O,在某些情况下这可能会更快。

尝试使用关闭它std::cout.sync_with_stdio(false);