缓冲区刷新:“\ n”与std :: endl

时间:2012-03-11 00:07:41

标签: c++ optimization

  

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

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

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

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

  3. 这让我感到奇怪:显然,除了最大的输出之外,其他所有内容的优势都非常小<且非常明显,但使用"\n"比使用std::endl更快,或者"\n"是否也刷新缓冲区?

2 个答案:

答案 0 :(得分:9)

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

在典型的I / O中,输出在写入目标器件之前进行缓冲。这样,当写入慢速访问设备(如文件)时,它不必在每个字符后访问设备。刷新“冲洗”缓冲区到设备上,导致明确的性能开销。

-Adapted from:C++ - endl and flushing the buffer

答案 1 :(得分:0)

我想补充一点,我认为在流中编写'\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;
}

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