如何在不刷新缓冲区的情况下打印换行符?

时间:2015-06-21 18:01:45

标签: c++

我正在尝试使用c ++试图弄清楚如何尽可能快地打印从0到n的数字。

起初我只是用循环打印所有数字:

for (int i = 0; i < n; i++) 
{
    std::cout << i << std::endl;
} 

但是,我认为这会在输出的每一个数字后刷新缓冲区,而且肯定需要一些时间,所以我试图先将所有数字打印到缓冲区(或实际上直到它已满为止似乎然后似乎自动刷新)然后立即冲洗它们。但是,似乎在刷新缓冲区之后打印\ n就像std :: endl一样,所以我省略了它:

for (int i = 0; i < n; i++) 
{
    std::cout << i << ' ';
} 
std::cout << std::endl;

这似乎比第一个例子快了大约10倍。但是我想知道如何将所有值存储在缓冲区中并立即刷新所有值,而不是每次充满时都让它冲洗,所以我有几个问题:

  1. 是否可以在不刷新缓冲区的情况下打印换行符?
  2. 如何更改缓冲区大小以便我可以将所有值存储在其中并在最后冲洗它?
  3. 这种输出文字的方法是愚蠢的吗?如果是这样,为什么,以及什么是更好的替代品呢?
  4. 编辑:似乎我的结果偏向于滞后系统(智能手机的终端应用)......使用更快的系统,执行时间没有显着差异。

1 个答案:

答案 0 :(得分:3)

TL; DR:一般情况下,使用'\n'代替std::endl的速度要快std::endl

<强>说明: std::endl会导致刷新缓冲区,而'\n'则不会。 但是,您可能会或可能不会注意到任何加速,具体取决于您应用的测试方法。

考虑以下测试文件:

<强> endl.cpp

#include <iostream>

int main() {
    for ( int i = 0 ; i < 1000000 ; i++ ) {
        std::cout << i << std::endl;
    }
}

<强> slashn.cpp

#include <iostream>

int main() {
    for ( int i = 0 ; i < 1000000 ; i++ ) {
        std::cout << i << '\n';
    }
}

这两个都是在我的linux系统上使用g++编译的,并经过以下测试:

<强> 1。 time ./a.out

对于endl.cpp,需要19.415秒 对于slashn.cpp,它需要19.312s。

<强> 2。 time ./a.out >/dev/null

对于endl.cpp,它需要0.397秒 对于slashn.cpp,它需要0.153s

第3。 time ./a.out >temp

对于endl.cpp,它需要2.255秒 对于slashn.cpp,它需要0.165s

结论: '\n'肯定更快(甚至实际上),但速度的差异可能取决于其他因素。在终端窗口的情况下,限制因素似乎取决于终端本身可以多快地显示文本。由于文本显示在屏幕上,并且需要自动滚动等,因此执行中会出现大量减速。另一方面,对于普通文件(如上面的temp示例),刷新缓冲区的速率会对它产生很大影响。对于某些特殊文件(如上面的/dev/null),由于数据刚刚陷入黑洞,因此​​刷新似乎没有效果。