Why is std::cout so time consuming?

std::cout ultimately results in the operating system being invoked.

If you want something to compute fast, you have to make sure that no external entities are involved in the computation, especially entities that have been written with versatility more than performance in mind, like the operating system.

Want it to run faster? You have a few options:

  1. Replace << std::endl; with << '\n'. This will refrain from flushing the internal buffer of the C++ runtime to the operating system on every single line. It should result in a huge performance improvement.

  2. Use std::ios::sync_with_stdio(false); as user Galik Mar suggests in a comment.

  3. Collect as much as possible of your outgoing text in a buffer, and output the entire buffer at once with a single call.

  4. Write your output to a file instead of the console, and then keep that file displayed by a separate application such as Notepad++ which can keep track of changes and keep scrolling to the bottom.

As for why it is so “time consuming”, (in other words, slow,) that’s because the primary purpose of std::cout (and ultimately the operating system’s standard output stream) is versatility, not performance. Think about it: std::cout is a C++ library function which will invoke the operating system; the operating system will determine that the file being written to is not really a file, but the console, so it will send the data to the console subsystem; the console subsystem will receive the data and it will start invoking the graphics subsystem to render the text in the console window; the graphics subsystem will be drawing font glyphs on a raster display, and while rendering the data, there will be scrolling of the console window, which involves copying large amounts of video RAM. That’s an awful lot of work, even if the graphics card takes care of some of it in hardware.

As for the C# version, I am not sure exactly what is going on, but what is probably happening is something quite different: In C# you are not invoking Console.Out.Flush(), so your output is cached and you are not suffering the overhead incurred by C++’s std::cout << std::endl which causes each line to be flushed to the operating system. However, when the buffer does become full, C# must flush it to the operating system, and then it is hit not only by the overhead represented by the operating system, but also by the formidable managed-to-native and native-to-managed transition that is inherent in the way it’s virtual machine works.

Leave a Comment