是否有可能使 C++ iostream std::cout 与 cstdio printf() 一样高性能?

Is it possible to make C++ iostream std::cout be as performant as cstdio printf()?

提问人:Lone Learner 提问时间:3/22/2021 最后编辑:Lone Learner 更新时间:3/22/2021 访问量:120

问:

注意:这不是现有问题的重复。我已经经历了所有这些,但我无法像 .示例代码和证据如下所示。std::ios::sync_with_stdio(false)coutprintf

我有三个源代码文件:

// ex1.cpp

#include <cstdio>
#include <chrono>

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 10000000; i++) {
        printf("%d\n", i);
    }
    auto t2 = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
    fprintf(stderr, "%lld\n", duration.count());
}
// ex2.cpp

#include <iostream>
#include <chrono>

int main()
{
    auto t1 = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 10000000; i++) {
        std::cout << i << '\n';
    }
    auto t2 = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
    std::cerr << duration.count() << '\n';
}
// ex3.cpp

#include <iostream>
#include <chrono>

int main()
{
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    auto t1 = std::chrono::high_resolution_clock::now();
    for (int i = 0; i < 10000000; i++) {
        std::cout << i << '\n';
    }
    auto t2 = std::chrono::high_resolution_clock::now();
    auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
    std::cerr << duration.count() << '\n';
}

我永远不会在我的代码中混合和使用,所以中使用的黑客对我来说是可以的。cstdioiostreamex3.cpp

我在带有固态驱动器的 macOS 上使用 clang++ 编译它们。

clang++ -std=c++11 -O2 -Wall -Wextra -pedantic ex1.cpp -o ex1
clang++ -std=c++11 -O2 -Wall -Wextra -pedantic ex2.cpp -o ex2
clang++ -std=c++11 -O2 -Wall -Wextra -pedantic ex3.cpp -o ex3

现在我运行它们并计时。

$ time ./ex1 > out.txt
1282

real    0m1.294s
user    0m1.217s
sys     0m0.071s

$ time ./ex1 > out.txt
1299

real    0m1.333s
user    0m1.221s
sys     0m0.072s

$ time ./ex1 > out.txt
1277

real    0m1.295s
user    0m1.214s
sys     0m0.070s
$ time ./ex2 > out.txt
3102

real    0m3.371s
user    0m3.037s
sys     0m0.075s

$ time ./ex2 > out.txt
3153

real    0m3.164s
user    0m3.073s
sys     0m0.075s

$ time ./ex2 > out.txt
3136

real    0m3.150s
user    0m3.051s
sys     0m0.077s
$ time ./ex3 > out.txt
3118

real    0m3.513s
user    0m3.045s
sys     0m0.080s

$ time ./ex3 > out.txt
3113

real    0m3.124s
user    0m3.042s
sys     0m0.077s

$ time ./ex3 > out.txt
3095

real    0m3.107s
user    0m3.029s
sys     0m0.073s

即使我将输出重定向到 ,结果也非常相似。结果与优化级别也非常相似。/dev/null-O3

两者都比 ?是否可以在任何提供与 2 相当的速度的情况下使用?ex3ex2ex1std::coutprintf

C++ 同步 IOSTREAM CSTDIO

评论

0赞 Some programmer dude 3/22/2021
我要问你的问题是:为什么这是一个问题?你做了什么导致输出成为你程序中的主要瓶颈?
4赞 Lone Learner 3/22/2021
@Someprogrammerdude 这是一个问题,因为我不明白为什么我得到的结果与关于这个主题的其他答案不一致。我没有做任何导致输出成为瓶颈的事情。我试图了解禁用同步是否确实会导致性能更好的副作用,如果不是,为什么不呢?stdio
0赞 Galik 3/22/2021
在程序本身内部进行计时可能是值得的。可能是(例如)更多的代码被放入二进制文件中,所以启动时间更长?
0赞 Galik 3/22/2021
我只是没有得到和你一样的结果。在我的测试中,它们变得越来越快。和(虽然是 GCC v10)。0m1.309s0m1.274s0m1.041s
2赞 Lone Learner 3/22/2021
@Galik @churill 确认在 Linux 上,我得到的结果与您相似。 大约需要 1100 毫秒,大约需要 1300 毫秒,大约需要 1000 毫秒。因此,我的问题中的问题看起来像是我的macOS系统上的问题。g++ 8.3.0ex1ex2ex3Apple clang version 12.0.0 (clang-1200.0.32.27)

答: 暂无答案