endl and flushing the buffer
Output is generally buffered before it's written to the intended device. That way, when writing to slow to access devices(like files), it doesn't have to access the device after every single character.
Flushing means emptying the buffer and actually writing it to the device.
Is it necessary for endl to flush buffer?
if a new line is inserted, then the buffer will be flushed automatically
Not necessarily, and not for all streams. It's common for std::cout
(and the standard output stream it sends data to) to be line-buffered, but not universal. Some implementations, for example, only line-buffer stdout if output is going to a terminal, and fully-buffer it otherwise (if output is redirected to a pipe, for example).
And that's just for standard output. Other streams like file I/O are almost always fully-buffered and the buffer will only be flushed when it either fills up or its flushed explicitly.
Buffer flushing: \n vs. std::endl
Using '\n' does not flush the buffer and is indeed faster than using std::endl.
In typical I/O, output is buffered before it's written to the intended device. This way, when writing to slow to access devices(like files), it doesn't have to access the device after every single character. Flushing "flushes" the buffer onto the device, causing a definite performance overhead.
-Adapted from: C++ - endl and flushing the buffer
how endl mainly affects fully buffered streams?
There are three main buffering strategies used for output streams:
- No buffering - Every write to the stream is immediately written to the underlying output device.
- Line buffering - Writes to the stream are stored in memory until a newline character is written or the buffer is full, at which point the buffer is flushed to the underlying output device.
- Full buffering - Writes to the stream are stored in memory until the stream's internal buffer is full, at which point the buffer is flushed to the underlying output device.
why endl mainly affects the fully buffered streams
This should be fairly apparent from the descriptions above. If the stream is unbuffered then std::endl
doesn't do any extra work; there is no buffer to flush. If the stream is line buffered, then writing a newline will flush the buffer anyway, so std::endl
doesn't do anything extra. Only for a fully buffered stream does std::endl
do any extra work.
how cout is not a fully buffered stream?
The C++ language doesn't specify the buffering strategy used for std::cout
, but most implementations use either no buffering or line buffering when the program's standard output stream is hooked up to a terminal. If stdout is redirected to something else, like a file, many implementations will switch to using a fully buffered stream for std::cout
.
How to flush buffer manually?
You can see whether your stream is buffered by sleeping between outputs, e.g.:
#include <iostream>
#include <thread>
int main()
{
for (int i = 0; i < 50; i++)
{
char ch = 'a';
std::cout << ch << "\n";
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
}
On some platforms you might need to enable buffering on stdout
by calling setvbuf
:
std::setvbuf(stdout, nullptr, _IOFBF, BUFSIZ);
Related Topics
How to Switch Between Blas Libraries Without Recompiling Program
Changing the Current Directory in Linux Using C++
How to Read Linux File Permission Programmatically in C/C++
Gmon.Out Is Not Written After Compiling with Gcc -Pg -G
What Exif Lib How to Use from a Qt Program (On Embedded Linux)
How to Avoid Multiple Definition Linking Error
Find Argc and Argv from a Library
Openprocess/Readprocessmemory/Writeprocessmemory/Closehandle Equivalent
Press Anykey to Continue in Linux C++
Iterate Through Struct and Class Members
Is the Memory Allocated for Struct Members Continguous? What If a Struct Member Is an Array
Difference Between *(Pointer + Index) and Pointer[]