C++程序员是否应频繁使用std::flush?

23

建议C++程序员经常编写类似以下的代码:

std::cout << "output: " << i << " and " << j << std::flush;
//more
std::cout << "ending newline." << std::endl; //endl does flush

换句话说,在没有使用 endl 的输出行中,我们是否应该经常使用 flush,以防万一?或者在大多数平台上这已经不再需要了吗?


5
std::endl 会自动调用 flush,因此使用 "\n" 的唯一原因是不想刷新缓冲区。 - SheetJS
23
只有当他们频繁上厕所时。 - David G
1
我发现最大的清空使用案例是文件I/O。通常在我继续之前,我必须要写出文件。(以防止在意外崩溃或断电时数据丢失)。 - Mysticial
2
@Mysticial:std::flushstd::endl在意外断电时 不能 防止数据丢失,仅能在意外崩溃时起作用。它们会刷新到操作系统,但不会刷新到磁盘。 - Mooing Duck
5
“使用\n的唯一原因是如果您不想刷新” - 您的意思是不使用\n的唯一原因是如果您想要刷新。 - Christian Rau
显示剩余8条评论
2个回答

20

一般情况下,程序不需要频繁刷新缓冲区。刷新缓冲区是在以下几种情况下需要使用的:

  • 与人或其他系统进行交互:在等待输入之前清空输出缓冲区是明智的。
  • 暂时休眠一段时间:在长时间休眠或等待之前进行刷新可以简化日志文件的检查、大多数时候使数据库保持一致等。

如果不需要缓冲区,则最好在一开始禁用缓冲区,而不是频繁刷新。

大多数情况下,启用缓冲区对程序有益。有时它们会生成一些字符,有时它们会输出一堆行。

在我几十年的工程经验中,最显著的性能提升通常是通过改进缓冲区实现的。有时通过将默认的FILE缓冲区大小从512字节(默认值)增加到4K或32K(有时更高)。有时通过添加缓存层。通常每次通过操作系统的i/o系统旅行都会带来很高的开销。减少系统调用的总数量(通常)是一种简单而高效的方案来提高性能。


1
我认为在等待输入之前不需要刷新输出。它们默认是绑定在一起的。 - Mooing Duck
@MooingDuck 没错。关于C++标准流,请求输入之前无需刷新:http://en.cppreference.com/w/cpp/io/basic_ios/tie(特别是注意事项部分)。 - Oberon
@MooingDuck:我相信这只适用于特别绑定在一起的cincout。但是其他的ostream必须明确地单向或双向同步。 - wallyk
2
“默认情况下,标准流cin、cerr和clog与cout绑定。同样,它们的宽字符版本wcin、wcerr和wclog也与wcout绑定。”但对于其他输出流,您当然需要手动tie()它们(而不是手动刷新)。 - Oberon

15

通常情况下,频繁调用flush不是一个好习惯,因为如果你经常写入IO, 而频繁调用flush会导致程序变慢。你可以通过显式地使用std::endlstd::flush来控制flush的操作(std::endl会将\n插入到流中,然后再调用flush)。

@StackedCrooked in the C++ Lounge 进行了一项关于flush和不flush成本的实验: http://coliru.stacked-crooked.com/view?id=55c830cf9a144559f31963de41fa9405-f674c1a6d04c632b71a62362c0ccfc51

在重复使用flush时,不flush的性能表现相对较好,而每次调用flush都会增加一定的开销: 手动使用std::flush并不是很必要。只需在程序结束或关键代码段结束时执行一次即可。

还应该注意,在与用户交互之前可能需要刷新一下输出流,以免在日志文件或其他地方中遗漏了用户应该看到的内容。

编辑: 相关比喻: In simple terms, what is the purpose of flush() in ostream


话虽如此,我几乎总是使用std::endl。在大多数情况下,程序用户立即获得信息的可用性超过了不刷新的性能优势。 - StackedCrooked
@StackedCrooked:实际上,根据数据来看,我几乎可以说应该经常进行清空操作。性能损失比我想象的要小得多。那是5.2毫秒的惩罚吗? - Mooing Duck
是的,成本大约为10微秒,或每秒100,000次刷新。 - StackedCrooked
@StackedCrooked: 为什么你要以0.1毫秒为单位输出? - Mooing Duck
1
“嗯,我的结果略有不同。”(http://coliru.stacked-crooked.com/view?id=69a5c32aeb57fc9e165e1e165e83fe94-f674c1a6d04c632b71a62362c0ccfc51) - Mooing Duck
@MooingDuck 在 [0, 100] 范围内的数字更容易阅读。 - StackedCrooked

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接