Christian
Christian

Reputation: 29

C++, MinGW, Windows: printing numbers using std::cout is painfully slow

I just got a new laptop, and after installing MinGW, the execution time of simple programs is atrocious. Below is a simple for-loop I wrote.

#include <iostream>
using namespace std;

int main()
{
    for(int i=0;i<10000;i++)
    {
        cout<<i<<endl;
    }
    return 0;
}

On my laptop with a ryzen 9 4000 cpu running Windows, it took 18.9 seconds to execute. I have tried using different IDEs and reinstalling MinGW, but the same problem still persists.

Any ideas on how to make this run faster?

Upvotes: 2

Views: 575

Answers (1)

Richard E
Richard E

Reputation: 3422

GCC or clang (and thus your setup using MinGW)

Apply the suggestions from the comments:

  • Most important: Use std::ios_base::sync_with_stdio(false); for the reasons explained here. There is synchronization overhead if you don't do this. If you only use c++ streams, which you probably want, you do not need this synchronization. If this is not done, it prevents line buffering, for the reasons given here.
  • Use '\n' instead of std::endl. std::endl flushes the stream. This slows it down. (Note: This most likely only has an effect when you redirect the output to a text file. When printing to a terminal, the stream will most likely be line buffered (or maybe completely unbuffered). In this case, it doesn't make a difference, printing a newline will also cause the stream to be flushed)
  • Enable -Og (optimizations suitable for debugging) or -O3 (full optimizations) when calling the compiler (see your compilers documentation on optimization, e.g. this page for GCC)

Then, you get this program:

#include <iostream>

int main()
{
    std::ios_base::sync_with_stdio(false);
    for(int i = 0; i < 10000; ++i) {
        std::cout << i << '\n';
    }
    return 0;
}

The code you posted ran 7 seconds on my windows 10 machine, when printing to the windows command line. This runs in a few (maybe hundred?) milliseconds when compiled without optimizations and in less than 50ms when compiled with optimizations. Most of the change -- for me -- comes from the sync_with_stdio call.

MSVC

MSVC has std::cout completely unbuffered by default, even after calling std::ios_base::sync_with_stdio(false);. Here, it helps to manually set the stream to be line-buffered using (as suggested in the linked post) (docs for setvbuf):

setvbuf(stdout, 0, _IOLBF, 4096)

Upvotes: 4

Related Questions