15
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>

int main(int argc, char* argv[])
{
    std::clock_t start;
    double duration;    

    std::cout << "Starting std::cout test." << std::endl;
    start = std::clock();

    for (int i = 0; i < 1000; i++)
    {
        std::cout << "Hello, World! (" << i << ")" << std::endl;
    }

    duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Ending std::cout test." << std::endl;
    std::cout << "Time taken: " << duration << std::endl;

    std::system("pause");

    std::cout << "Starting std::printf test." << std::endl;
    start = std::clock();

    for (int i = 0; i < 1000; i++)
    {
        std::printf("Hello, World! (%i)\n", i);
        std::fflush(stdout);
    }

    duration = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Ending std::printf test." << std::endl;
    std::cout << "Time taken: " << duration << std::endl;

    system("pause");

    return 0;
}

现在,这里是前五次运行的时间:

  • std::cout 测试:1.125秒;printf 测试:0.195
  • std::cout 测试:1.154秒;printf 测试:0.230
  • std::cout 测试:1.142秒;printf 测试:0.216
  • std::cout 测试:1.322秒;printf 测试:0.221
  • std::cout 测试:1.108秒;printf 测试:0.232

如您所见,使用printf然后fflushing 比使用 ing 花费的时间大约少 5 倍std::cout

尽管我确实希望使用std::cout's<<运算符可能会慢一些(几乎是最小的),但我并没有为这种巨大的差异做好准备。我在做一个公平的测试吗?如果是这样,那么是什么让第一个测试比第二个测试慢得多,如果他们基本上做同样的事情?

4

6 回答 6

12

尝试这个:

#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <iostream>

int main(int argc, char* argv[])
{
#if defined(NOSYNC)
    std::cout.sync_with_stdio(false);
#endif

    std::cout << "Starting std::cout test." << std::endl;

    std::clock_t start = std::clock();

    for (int i = 0; i < 1000; i++)
    {   
        std::cout << "Hello, World! (" << i << ")" << std::endl;
    }   

    clock_t mid = std::clock();

    for (int i = 0; i < 1000; i++)
    {   
        std::printf("Hello, World! (%i)\n", i); 
        std::fflush(stdout);
    }   

    std::clock_t end = std::clock();

    std::cout << "Time taken: P1 " << ((mid-start)*1.0/CLOCKS_PER_SEC) << std::endl;

    std::cout << "Time taken: P2 " << ((end-mid)*1.0/CLOCKS_PER_SEC) << std::endl;


    return 0;
}

然后我得到:

> g++ -O3 t13.cpp
> ./a.out
# lots of lines deleted
Time taken: P1 0.002517
Time taken: P2 0.001872

> g++ -O3 t13.cpp -DNOSYNC   
> ./a.out
# lots of lines deleted
Time taken: P1 0.002398
Time taken: P2 0.001878

所以 P2 时间不会改变。
但是您可以使用std::cout.sync_with_stdio(false);. 因为代码不再尝试保持两个流 (std::cout stdout) 同步。如果您正在编写纯 C++ 并且仅使用 std::cout 不是问题。

于 2012-08-20T21:33:01.870 回答
10

对于真正的苹果对苹果的比较,重新编写你的测试,以便测试用例之间唯一改变的是正在使用的打印函数:

int main(int argc, char* argv[])
{
    const char* teststring = "Test output string\n";
    std::clock_t start;
    double duration;

    std::cout << "Starting std::cout test." << std::endl;
    start = std::clock();

    for (int i = 0; i < 1000; i++)
        std::cout << teststring;
    /* Display timing results, code trimmed for brevity */

    for (int i = 0; i < 1000; i++) {
        std::printf(teststring);
        std::fflush(stdout);
    }
    /* Display timing results, code trimmed for brevity */
    return 0;
}

这样,您将只测试printfcout函数调用之间的差异。您不会因多次<<调用等而产生任何差异。如果您尝试这样做,我怀疑您会得到截然不同的结果。

于 2012-08-20T20:45:36.957 回答
4

利用

cout << "\n";

以防止缓冲。快多了

于 2017-04-28T14:37:18.773 回答
2

大约 10 年前,Scott Meyers 测试了iostreamscanf/printf的效率。取决于编译器和环境,有时 scanf/printf 比 iostream 快 20%,有时甚至快 200%。但是 iostream 从来没有比 scanf/printf 快。根据其他两个给定的示例,scanf/printf 仍然比 iostream 快。然而,迈耶斯说:“在一个真正有用的程序上,不会有任何差异。” 根据 Google 的编程风格([ http://google-styleguide.googlecode.com/svn/trunk/cppguide.html]),除了日志记录之外,不应使用流。iostream 的替代方法是自己封装 scanf/printf。

于 2017-04-28T14:59:39.243 回答
0

我只有一台计算机的编程范围,所以没有太多测试。无论如何,std::cout 在我的构建中使用精确的详细代码更快。我正在使用 Cpp14。

我只是认为某些人会选择 C++。是的,C 是很棒的语言,但从逻辑上讲,我看不出 printf 如何比 std cout 更快。Printf 必须在运行时从 void 指针进行类型转换。Cout 在编译时这样做。

于 2018-05-22T02:22:08.107 回答
0

我在笔记本电脑上尝试了这个测试,运行 Windows 10、WSL Ubuntu、CLion 2018、GCC。无优化:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <ctime>

int main(int argc, char *argv[]) {
    std::ios_base::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::clock_t start;
    double duration1, duration2;

    std::cout << "Starting std::cout test.\n";
    start = std::clock();

    for (int i = 0; i < 100000; i++) {
        std::cout << "Hello, World! (" << i << ")" << std::endl;
    }

    duration1 = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Starting std::printf test.\n";
    start = std::clock();

    for (int i = 0; i < 100000; i++) {
        std::printf("Hello, World! (%i)\n", i);
        std::fflush(stdout);
    }

    duration2 = (std::clock() - start) / (double) CLOCKS_PER_SEC;

    std::cout << "Time taken: cout " << duration1 << std::endl;
    std::cout << "Time taken Printf: " << duration2 << std::endl;

    return 0;
}

结果:

Test1: Cout: 2.25, Printf: 2.45312  (Cout run first)
Test2: Cout: 2.42188, Printf: 2.07812 (Printf Run first)
Test3: Cout: 2.26562, Printf: 2.25 (Cout run first)
Test4: Cout 2.46875, Printf: 2.57812 (Printf run first)

TL;DR:使用std::ios_base::sync_with_stdio(false)std::cin.tie(nullptr)将这两个功能带到几乎相同的位置。

于 2019-03-23T22:00:44.247 回答