【问题标题】:How can I print a newline without flushing the buffer?如何在不刷新缓冲区的情况下打印换行符?
【发布时间】:2015-06-21 18:01:45
【问题描述】:

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

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

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

但是,我认为这会在它输出的每个数字之后刷新缓冲区,当然这必须花费一些时间,所以我尝试首先将所有数字打印到缓冲区(或者实际上直到它看起来已经满了,然后看起来自动冲洗),然后一次冲洗。但是,似乎在像 std::endl 一样刷新缓冲区之后打印一个 \n 所以我省略了它:

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

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

  1. 是否可以在不刷新缓冲区的情况下打印换行符?
  2. 如何更改缓冲区大小,以便将所有值存储在其中并在最后刷新?
  3. 这种输出文本的方法很笨吗?如果是这样,为什么,以及什么是更好的选择?

编辑:我的结果似乎受到了滞后的系统(智能手机的终端应用程序)的影响......使用更快的系统,执行时间没有显着差异。

【问题讨论】:

  • 在写入之前尝试取消设置cout 上的unitbuf 标志。
  • 不要使用endl,因为它会强制刷新等。改用'\n'"\n"?或者您可以使用更精细的技巧将std::cout 的缓冲模式设置为完全缓冲。
  • std::cout &lt;&lt; '\n' 打印一个新行。除非有理由,否则不要手动冲洗。
  • 你会发现 nobar 的第三个答案很有趣stackoverflow.com/questions/4751972/…
  • '\n' 好像和endl的效果一样。使用 '\n' 或 endl 打印从 0 到 1,000,000 的数字大约需要 20 秒。没有它们只需要大约 3 秒。

标签: c++


【解决方案1】:

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.415s。
对于slashn.cpp,需要19.312s。

2。 time ./a.out &gt;/dev/null

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

3. time ./a.out &gt;temp

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

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

【讨论】:

  • 在输出到终端的情况下,'\n' 也可能刷新缓冲区。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-17
  • 2021-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-14
相关资源
最近更新 更多