【问题标题】:Will using fflush after printf slow down your program?printf 后使用 fflush 会减慢程序的速度吗?
【发布时间】:2015-11-18 09:01:17
【问题描述】:

我正在编写一些控制台程序,我注意到有时当我使用 print() 并且我的程序处于空闲状态时,并非所有内容都被打印出来(最后几行丢失了)。

最终会发生一些事情,并且确实会打印这些行,但通常当我关闭程序时,最后几行不存在。

所以我做了一些挖掘,看起来标准输出缓冲区并不总是清空,除非满足某些条件(换行?/换行?)。

所以我创建了一个“myprintf()”函数,它包装了 printf 以执行以下操作(在伪代码中):

printf(...);
fflush(stdout);

问题是,除了明显的额外函数调用开销之外,这是否会减慢我的程序速度? IE。这是一个糟糕的实践表现吗?

【问题讨论】:

  • 通常,这个问题的答案是... 测量!顺便说一句,我猜如果你的程序没有长时间的计算(以秒为单位),那么刷新将占总工作的很大一部分,但你不会注意到它,因为它只是几个毫秒。
  • 对于 C++,有许多与此主题相关的类似问题,关于使用 std::endl(添加换行符然后刷新输出)与 '\n'"\n"。查看stackoverflow.com/questions/8311058/…stackoverflow.com/questions/213907/c-stdendl-vs-n
  • 最简单的解决方法是始终以 '\n' 结束 printf() 格式字符串(结束输出行),因为这总是强制写入输出缓冲区(在操作系统中)。第二种方法是在提示用户输入时,在 printf() 之后的输入操作(如 scanf())将强制写入输出缓冲区(在 OS 中)。

标签: c++ c printf


【解决方案1】:

取决于几件事。

如果您的 printf 以换行符 (\n) 结尾,stdout 缓冲区将立即刷新并直接显示所有内容。这是stdout 缓冲区的默认行为。因此,在这种情况下,再次刷新确实会减慢您的程序速度,尽管只是很小的量。

现在,如果您没有以换行符结尾,stdout 将不会自动刷新,您确实需要 fflush 才能正确显示内容。然后它也会减慢程序的速度,尽管只是一点点。

您可以通过将缓冲区标准输出设置为在刷新前不等待换行符来完全避免您的问题。这会使您的包装器变得多余像这样:

setbuf(stdout, NULL);

保证每次stdout 中有任何内容都会被刷新。这将比您每次直接调用fflush() 稍微高效一些。

总之,除非您在非常严格的性能限制下运行,否则产生的开销可以忽略不计。

【讨论】:

  • 实际上,强制操作系统每次都处理输出缓冲区是对系统资源的消耗,而输出缓冲时并不存在。所以,一般来说,这行:setbuf(stdout, NULL); 会导致整体执行速度变慢,因为 printf() 在输出操作完成之前无法返回。
【解决方案2】:

是的,它会减慢速度。如果没有,则刷新将是默认行为。

从你发帖的语气来看,听起来你做的事情并没有引起过多的潮红。所以,除非你说出你害怕减速的原因,否则就赶紧走开。

【讨论】:

    【解决方案3】:

    是的,速度会变慢,不一定很明显;但它会存在。

    printf(); fflush(); 的更好替代方案是使用 setvbuf() 更改缓冲策略;对setvbuf(stdout,NULL,_IONBF,0); 的调用将确保对stdout 的每次写入都将被直接刷新(比每次显式调用fflush() 更好)。

    【讨论】:

    • 谢谢,这很有趣会去。
    【解决方案4】:

    IO 通常是最耗时的操作。所以不必要的刷新可能会减慢你的程序。但是您应该对此做两件事,因为如果输出是终端,则在遇到换行符或读取之前(在同一终端上......),刷新是自动的。所以我能想象的唯一用例可能是:

    • 定期输出单个字符(.* 或...)以显示冗长操作的进程。没有冲洗,什么都看不到
    • 希望程序输出通过管道传输到另一个程序(例如tee),同时希望进度立即出现在屏幕上

    TL/DR:对于常见的用法,减速不会很明显,但没用。

    【讨论】:

    • 另一个用例(我的)是你打印的地方:“waiting for x...”然后“done\n”将它保持在同一行,两者之间可能有无限的时间打印 :)
    猜你喜欢
    • 1970-01-01
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-23
    • 1970-01-01
    • 2014-09-28
    • 1970-01-01
    相关资源
    最近更新 更多