可能重复:
C++:“std::endl” vs“\ n”
在 Accelerated C++ 中提到了两件事:
大多数系统花费大量时间将字符写入输出设备。因此,C ++ 积累要写入缓冲区的字符并等待刷新缓冲区。
一种缓冲区可以被刷新的方法是如果我们明确告诉它这样做,使用
std::endl
。
这让我想知道:显然,除了最大的输出之外,好处非常小且不可感知,但是使用 "\n"
比使用 std::endl
快,还是 "\n"
也会刷新缓冲区?
可能重复:
C++:“std::endl” vs“\ n”
在 Accelerated C++ 中提到了两件事:
大多数系统花费大量时间将字符写入输出设备。因此,C ++ 积累要写入缓冲区的字符并等待刷新缓冲区。
一种缓冲区可以被刷新的方法是如果我们明确告诉它这样做,使用 std::endl
。
这让我想知道:显然,除了最大的输出之外,好处非常小且不可感知,但是使用 "\n"
比使用 std::endl
快,还是 "\n"
也会刷新缓冲区?
使用 '\n' 不会刷新缓冲区,实际上比使用 std::endl 更快。
在典型的 I/O 操作中,输出会被缓冲起来,然后再写入到目标设备。这样,在写入到访问速度较慢的设备(例如文件)时,就不必每个字符都访问一次该设备。刷新操作会将缓冲区“刷新”到设备中,从而导致明显的性能开销。
g++
实现中,我发现它在几个场合比 C 标准输入输出库略快。 - Matteo Italia我想补充一下,我认为将'\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
和其他特殊化。