【问题标题】:Buffer flushing: "\n" vs. std::endl [duplicate]缓冲区刷新:“\n”与 std::endl [重复]
【发布时间】:2012-03-27 22:08:14
【问题描述】:

可能重复:
C++: “std::endl” vs “\n”

Accelerated C++中,提到了两件事:

  1. 大多数系统花费大量时间将字符写入输出设备。因此,C++ 将要写入的字符累积到缓冲区中并等待缓冲区被刷新。

  2. 可以刷新缓冲区的一种方法是,如果我们使用 std::endl 明确告诉它这样做。

这让我想知道:显然,除了最大的输出之外,所有的好处非常很小且不明显,但使用"\n" 比使用std::endl 更快,或者"\n"还刷新缓冲区?

【问题讨论】:

  • 是的,这是一个实现细节,所以你不会得到明确的答案。我的猜测是它在大多数实现中都有所不同,但这不一定是真的。
  • @Carl -- 诚然,我没有,我什至不知道该怎么做。我正在看这本书,我很好奇,所以我想问一下。

标签: c++ optimization


【解决方案1】:

使用 '\n' 不会刷新缓冲区,并且确实比使用 std::endl 更快。

在典型的 I/O 中,输出在写入预期设备之前会被缓冲。这样,当写入缓慢以访问设备(如文件)时,它不必在每个字符之后访问设备。刷新会将缓冲区“刷新”到设备上,从而导致一定的性能开销。

-改编自:C++ - endl and flushing the buffer

【讨论】:

  • 对于一些[通常]非常小的“更快”值;-)
  • @pst:好吧,当将大量数据输出到文件时,它实际上可能会影响性能(我曾经在 CSV 中写入几十 MB 的数据时发生过这种情况)。
  • @MatteoItalia 是的,我没想到相反的 :(
  • @MatteoItalia:另一方面,iostream 并不是输出东西的最快方式,所以还有很多其他的东西会对性能产生负面影响。
  • @SigTerm: iostreams 的设计很糟糕,但在g++ 的实现中,我发现它比C stdio 稍快。
【解决方案2】:

我想补充一点,我认为将'\n' 写入流的含义可能与在第三方库中写入std::endl/std::flush 不同。

例如,我在当前项目中使用基于 ostream 的记录器。该记录器使用std::stringstream 功能进行输出格式化,但具有用于刷新的重写操纵器。这允许在不刷新的情况下将'\n' 写入日志并简化代码。

这是一个伪代码示例:

class MyStream
{
    // [cut]
    std::stringstream m_buffer;
    // [cut]
};

// friends:
template <typename Printable>
MyStream& operator<<(MyStream& stream, const Printable& value)
{
     stream.m_buffer << value;
}

typedef decltype(std::flush) TManipulator;
template <>
MyStream& operator<<(MyStream& stream, const TManipulator& manipulator)
{
     if ( manipulator == std::flush || manipulator == std::endl )
         stream.sendLogLine();
     else
         stream.m_buffer << manipulator;
}

// usage sample
void main()
{
    getLoggerStream() << "hello" << std::endl;
}

附:我不喜欢继承 std::stringstream,所以 MyStream 是一个适配器。如果我想让'\n' 刷新,我应该重新实现更多功能,包括char*std::string 和其他专业化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-10-01
    • 2018-04-13
    • 2018-06-11
    • 2015-04-19
    • 2020-12-12
    • 2013-08-16
    相关资源
    最近更新 更多