添加`g ++`的`-std =`标志时,C ++打印到终端的速度要慢得多?

时间:2019-03-01 11:26:17

标签: c++ performance g++ runtime c++14

摘要

我有以下C ++代码:

#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;
}

使用g++ Source.cpp -O3编译后运行代码时,我的计算机上的运行时间通常为 25秒。但是,如果我使用g++ Source2.cpp -std=c++14 -O3进行编译,则我得到的运行时间将超过 90秒

更多详细信息

我正在使用g++版本8.2.0进行编译,该版本将__cplusplus定义为201402L。因此,默认情况下,它应该在C ++ 14标准下进行编译。

因此,当我添加-std=c++14标志时,代码运行速度会慢得多,这似乎很奇怪。我还注意到,如果我使用-std=c++11,代码的运行速度也一样慢,因此似乎仅使用-std=就是问题所在。

注意1:我在循环内使用printf()而不是cout,因为我知道前者更快。

注意2:我的问题与Code running slower with g++ -std=c++0x完全不同,即使标题听起来很相似。

更新

基于注释中的建议,我尝试通过写入文件而不是打印到终端来运行代码。在这种情况下,运行时间没有显着差异

我还在Windows的不同终端上运行了代码:cmdPowerShellcmder。我发现,尽管每个终端上的确切运行时间都不同,但是没有-std=标志的代码通常仍然运行至少快两倍

(在终端上运行程序时,请确保在每次运行前都启动一个新的终端,以确保终端历史不会影响运行时间。)

因此,具体问题是:

为什么在代码输出到终端时添加标志会导致代码运行缓慢?

更新2

运行更多的测试后,我意识到使用终端在短时间内(几秒钟或不到一秒钟)打印出代码的区别可以忽略不计。

似乎我获得的运行时间差异是计算机环境所特有的,并且可能无法复制。

尽管如此,迈克尔在他的回答和评论中提供的见解还是有价值的,并且可能有助于解释其他人面临的类似性质的问题。

1 个答案:

答案 0 :(得分:1)

差异仅归因于终端。两种选择都写入终端,终端必须保持滚动历史记录,并绘制已写入字符的像素。该终端比仅吐出ASCII字符的简短基准测试要困难得多。

实际上,您的终端(和/或OS)非常慢。我在MAC终端上运行了相同的程序(与gcc-8.2.0一起编译),运行了0.175374秒,一次运行了0.186559秒。如果不收集大量的统计数据,无论有没有-std=c++14,我都看不到任何区别。

这似乎是一个非常慢的终端(比MAC终端慢100倍)的问题,而不是代码本身。您的终端很可能在收集历史记录时变慢,因此第二次运行它会变慢(无论编译标志如何)。

在看到更新后的问题后进行编辑:

默认值为-std=gnu++14可能会执行一些非标准的优化,从而使终端运行得更快。通过-std=c++14时,gnu扩展名已关闭。

作为参考,请查看compiling with std c11...。据此,-std=c++14意味着_GNU_SOURCE不再定义,并且是printf could be used的另一种实现。