我有以下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的不同终端上运行了代码:cmd
,PowerShell
,cmder
。我发现,尽管每个终端上的确切运行时间都不同,但是没有-std=
标志的代码通常仍然运行至少快两倍。
(在终端上运行程序时,请确保在每次运行前都启动一个新的终端,以确保终端历史不会影响运行时间。)
因此,具体问题是:
为什么在代码输出到终端时添加标志会导致代码运行缓慢?
运行更多的测试后,我意识到使用终端在短时间内(几秒钟或不到一秒钟)打印出代码的区别可以忽略不计。
似乎我获得的运行时间差异是计算机环境所特有的,并且可能无法复制。
尽管如此,迈克尔在他的回答和评论中提供的见解还是有价值的,并且可能有助于解释其他人面临的类似性质的问题。
答案 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的另一种实现。