2

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?

He3lixxx
  • 3,263
  • 1
  • 12
  • 31
Christian
  • 29
  • 2
  • 2
    Did you turn on optimizations? – NathanOliver May 27 '21 at 17:40
  • 2
    It's all that (essentially unbuffered) output, particularly when the console window needs to scroll. Redirect the output to a file – 1201ProgramAlarm May 27 '21 at 17:40
  • 1
    Related: https://stackoverflow.com/questions/14573424/c-does-cout-statement-makes-code-slower Have you tried replacing `endl` with `'\n'`? – alter_igel May 27 '21 at 17:41
  • 1
    `g++ -O3` and replace `endl` with `\n` - if you use a windows console to run it, it's that that slows it down though – Ted Lyngmo May 27 '21 at 17:42
  • Have you tried calling [`std::ios_base::sync_with_stdio(false)`](https://stackoverflow.com/questions/31162367/significance-of-ios-basesync-with-stdiofalse-cin-tienull) right after entering main? With this, and the other comments so far, it should be fast. – He3lixxx May 27 '21 at 17:43
  • 1
    Compiler flags and micro-optimizations aside, this is **hugely unusual**. Printing integers 1 to 10000 should **not** take around 20 seconds. I suspect that some virus scanner or other background process is halting execution and taking the bulk of that time. – Drew Dormann May 27 '21 at 17:44
  • 2
    Windows terminals are (or at least used to be) notoriously slow. Flushing after every output doesn't make it any faster. – Lukas-T May 27 '21 at 17:45
  • 1
    @Drew the code (compiled with a very old g++ 4.8 I had around) takes around 7 seconds on the windows command line on my windows 10 machine. Newline instead of flush and no stdio sync reduces it to a few hundred milliseconds, with the sync being the main culprit. – He3lixxx May 27 '21 at 17:52
  • 1
    Do you have an anti-virus program running? These programs are usually a bane to developers. – Thomas Matthews May 27 '21 at 18:44
  • 1
    @TedLyngmo thank you for the advice. I ran this with -O3 and it took only a few milliseconds to execute – Christian May 27 '21 at 20:25

1 Answers1

4

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)
He3lixxx
  • 3,263
  • 1
  • 12
  • 31
  • No, this doesn't run any faster. Test it on Windows if you wish. Swapping `endl` with `'\n'` has no difference on Windows if it's actually going to stdout. – Aykhan Hagverdili May 27 '21 at 18:05
  • 1
    Thank you for taking the time to help me out. The solution to this problem for me was to enable the optimization `-O3` – Christian May 27 '21 at 20:30