c++performanceg++runtimec++14

C++ printing to terminal much slower when adding g++'s -std=c++<##> flag?


Summary

I have this C++ code:

#include <iostream>
#include <chrono>

int main() {
    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();

    for (int counter = 0; counter < 80000;) {
        std::printf("%d\n", counter++);
    }

    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

    std::cout << std::endl << "Time difference (sec) = " << (std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count()) / 1000000.0 << std::endl;

    std::cin.get();
    return 0;
}

When running the code after compiling with g++ Source.cpp -O3, the run time is around 25 seconds on my machine. However, if I use g++ Source2.cpp -std=c++14 -O3, the run time is more than 90 seconds.

More details

I am compiling with g++ version 8.2.0, which defines __cplusplus to be 201402L. Therefore, by default, it should be compiling under the C++14 standard.

It therefore seems strange that the code would run much slower when I add the -std=c++14 flag. I also noticed that the code runs just as slow if I use -std=c++11, so it seems that just using -std is the problem.

I use printf() instead of cout within the loop because I am aware that the former is faster.

NB: My question is different than Code running slower with g++ -std=c++0x, even though the title looks similar.

Update

Based on suggestions in the comments, I tried making it write to a file instead of printing to the terminal. In that case, there was no significant difference in the run times.

I also ran the code in different terminals on Windows: cmd, PowerShell, and cmder. I found that, while the run times differ on each terminal, the code without the -std flag still generally runs at least twice as fast.

(To ensure that the terminal history does not impact the run time, I made sure to start a new terminal before each test.)

Update 2

After running more tests, I realized that the difference is negligible when using a terminal that prints the output in a short amount of time (a few seconds or less than a second).

It seems that the difference in run times I was getting is peculiar to the environment of my machine and may not be replicable.

Nevertheless, the insights provided by Michael in his answer and comments are valuable and might help explain problems of a similar nature faced by others.


Solution

  • The differences are solely due to the terminal. Both alternatives are writing to the terminal, which has to maintain scroll history, and draw the pixels of the written characters. The terminal works much harder than the short benchmark that only spits out ASCII characters.

    In fact, your terminal (and/or OS) are extremely slow. I have run the same program (compiled with gcc-8.2.0) on a MAC terminal and it ran 0.175374 seconds, once and 0.186559 another time. Without gathering significant amount of statistical data, I could not see any difference with and without -std=c++14.

    It seems an issue with an extremely slow terminal (more than 100 times slower than the MAC terminal), not with the code itself. Most likely your terminal becomes slower when it gathers history, so the second time it runs it gets slower (regardless of the compilation flags).

    Edit after seeing the updated question:

    It is possible that the default is -std=gnu++14 which performs some nonstandard optimization that makes the terminal run faster. When you pass -std=c++14 the gnu extension is turned off.

    For a reference, look at compiling with std c11.... According to it, -std=c++14 means that _GNU_SOURCE is no longer defined, and a different implementation of printf could be used.