【问题标题】:Extremely slow std::cout using MS Compiler使用 MS 编译器的 std::cout 非常慢
【发布时间】:2019-04-12 15:07:58
【问题描述】:

我正在打印计算的许多迭代的进度,输出实际上是其中最慢的部分,但只有当我使用 Visual C++ 编译器时,MinGW 才能在同一系统上正常工作。

考虑以下代码:

#include <iostream>
#include <chrono>

using namespace std;
#define TO_SEC(Time) \
    chrono::duration_cast<chrono::duration<double> >(Time).count();
const int REPEATS = 100000;

int main() {
    auto start_time = chrono::steady_clock::now();

    for (int i = 1; i <= REPEATS; i++) 
        cout << '\r' << i << "/" << REPEATS;

    double run_time = TO_SEC(chrono::steady_clock::now() - start_time);
    cout << endl << run_time << "s" << endl;
}

现在我用 MinGW ("g++ source.cpp -std==c++11") 编译时得到的输出是:

100000/100000 
0.428025s

现在我使用 Visual C++ Compiler 2013 年 11 月(“cl.exe source.cpp”)编译时得到的输出是:

100000/100000
133.991s

这很荒谬。我想到的是 VC++ 正在执行不必要的刷新。

有人知道如何预防吗?

编辑:设置是:

gcc 版本 4.8.2 (GCC),目标 i686-pc-cygwin

Microsoft (R) C/C++ 优化编译器版本 18.00.21005.1 for x86

Windows 7 Professional N 64 位,CPU i7-3630QM,2.4GHz,8.00GB RAM

【问题讨论】:

  • 您在这两种情况下都使用哪些编译器选项?它们是一样的吗?
  • 在 VS 中是 Release 还是 Debug 构建?
  • 这是默认选项,即:“g++ source.cpp -std=c++11”和“cl.exe source.cpp”
  • 我得到明显不同的数字:MinGW:21.6672s。 cl.exe:53.1926s。你用的是哪个版本的 MinGW 的 g++?
  • 该程序只需要 0.38 秒的唯一方法是缓冲输出,例如重定向到文件时。这也加快了 MSVC++ 的构建速度,在我的机器上为 0.64 秒。编写健全的代码是这里的主要指令,编写适合人眼的输出。

标签: c++ performance visual-c++ cout


【解决方案1】:

MSVC 中的std::cout 很慢 (https://web.archive.org/web/20170329163751/https://connect.microsoft.com/VisualStudio/feedback/details/642876/std-wcout-is-ten-times-slower-than-wprintf-performance-bug-in-c-library)。

这是我们的 C 和 C++ 标准库的不幸结果 设计了实现。问题是当打印到 控制台(而不是,比如说,被重定向到一个文件),我们的 C 默认情况下也不缓冲 C++ I/O。这有时会被 事实上,C I/O 功能类似于 printf() 和 puts() 暂时 在工作时启用缓冲。

Microsoft 建议进行此修复(以启用 cout/stdout 上的缓冲):

setvbuf(stdout, 0, _IOLBF, 4096)

你也可以试试:

cout.sync_with_stdio(false);

但可能不会有什么不同。

【讨论】:

  • 谢谢,setvbuf(stdout, 0, _IOLBF, 4096) 成功了(运行时 3.20018s )。
【解决方案2】:

避免使用 std::endl 而是使用 "\n"。 std::endl 应该按照标准刷新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-13
    • 1970-01-01
    • 2017-02-05
    • 1970-01-01
    • 2017-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多