C++ 系统时钟在c和c+中的性能+;11

C++ 系统时钟在c和c+中的性能+;11,c++,c,performance,c++11,time,C++,C,Performance,C++11,Time,我注意到,C风格的计算时间比使用C++11计算时间要快。如果执行需要更多的时间,差异会越来越小 #include <iostream> #include <chrono> #include <ctime> long fibonacci(int n) { if (n < 3) return 1; return fibonacci(n-1) + fibonacci(n-2); } int main() { /* C++11-Sty

我注意到,C风格的计算时间比使用C++11计算时间要快。如果执行需要更多的时间,差异会越来越小

#include <iostream>
#include <chrono>
#include <ctime>

long fibonacci(int n)
{
    if (n < 3) return 1;
    return fibonacci(n-1) + fibonacci(n-2);
}

int main()
{
    /* C++11-Style */
    std::chrono::time_point<std::chrono::system_clock> start, end;

    /* C-Style */
    clock_t c_start, c_end;
    double c_elapsed;

    /* Start */
    start = std::chrono::system_clock::now();
    c_start = clock();

    std::cout << "f(30) = " << fibonacci(30) << '\n';

    /* End */
    c_end = clock();
    end = std::chrono::system_clock::now();

    /* Compute Elasped time */
    c_elapsed = ((double)(c_end-c_start))/CLOCKS_PER_SEC;
    std::chrono::duration<double> elapsed_seconds = end-start;
    std::time_t end_time = std::chrono::system_clock::to_time_t(end);

    std::cout << "finished computation at " << std::ctime(&end_time)
              << "  elapsed time: " << elapsed_seconds.count() << "s\n";
    std::cout << "c_elapsed time: " << c_elapsed << "s" << std::endl;
}

为什么会这样?

你的测试很不公平!这有几个原因

打破基准 您有
clock()
调用仅围绕斐波那契计算,但
std::chrono::system\u clock::now()调用围绕斐波那契计算加上两个
clock()
调用

让我们再看一次:

  C                | C++11
  ====================================
  fibonacci(30)    | clock()
                   | fibonacci(30)
                   | clock()
您的C++11版本应该导致更高的持续时间,这似乎是完全合理的

使用独立的机制重新运行您的基准测试(例如,每个代码变体都有一个完全独立的文件),并增加计时计算的大小,以获得更有意义的结果;运行100次,取一个平均值,或者别的什么

不同语义 话虽如此,我一直认为:


我不知道这是为什么,但是,因此,比较
经过的秒数.count()
c\u经过的秒数
,并期望对结果做出任何确定的合理化,这在很大程度上是愚蠢的。

这个测试有几点错误

  • 这是一个样本

    谁知道下次运行时会发生什么。据我们所知,差异可能在0.002和-42.1723之间波动,该样本恰好显示了接近0.002的差异。如何知道结果是否可重复,或者如果只尝试一次,结果如何变化

  • 这是一个完全未知特征的时钟样本

    如果第一个时钟只能以0.00417783s的增量进行测量,第二个时钟只能以0.003686s的增量进行测量,但实验实际运行时间为0.005s,该怎么办?如果一个人不知道时钟测量得有多好,怎么知道结果的差异是否有意义

  • 它为每个时钟测量不同的东西

    第一个时钟测量包括对第二个时钟代码的两次调用。如果时钟不是从一个测量值改变到另一个测量值的唯一因素,那么如何知道结果的差异是否由时钟的差异来解释

  • 因此,测试毫无意义

    更好的测试应该:

  • 确定时钟的特性

    首先,人们需要知道时钟测量时间的精度。知道了这一点,我们就可以扩大实验规模,从而将低精度的影响降低到我们不关心的程度

  • 用两个时钟测量相同的东西

    把苹果和苹果比较一下。除了第一部分感兴趣的:时钟之外,这两个测量值应该没有区别

  • 抽取多个样本

    通过多次抽样,人们可以知道结果是否是一次侥幸(可能是由外部因素引起的),以及结果如何变化


  • 您的
    chrono
    点也考虑到了第二个
    时钟调用。您应该使用更大的工作负载以避免不准确和开销,在您启动基于
    chrono
    的时钟时,在缩放斐波那契参数时检查比率是否保持这种状态,您将包括调用
    c-style
    时钟的成本。你可以晚一点启动c型时钟,早一点停止。您应该将函数分为两个函数,每个函数只使用其中一种方法,否则会执行完全相同的工作负载。@CroCo:我没有否决这一个,但人们可能认为这个问题有点愚蠢/明显。事实上,这些人中的大多数可能无法说出我和机器人在下面的答案中确定的所有问题,因此我认为在这种情况下,你可以放心地忽略那些反对者。然而,如果你真的做了一些研究并学会了如何制定一个合适的基准,那也不会有什么坏处:这种懒惰在这里是不受欢迎的。@CroCo:我否决了你,因为坦率地说,这离“拥有CS学位”有千里之遥。这不仅仅是一点基础。您遇到的问题与C++11的速度似乎较慢这一事实无关,而与您没有关于如何构建远程公平基准的第一条线索这一事实有关。这不是一个我们可以在SO答案中解决的问题,因此您的问题非常不适合此网站。我觉得这不可能持续2年而不被注意,但您上面的数据是否显示system_clock::now()更快?使用clock()的版本需要.038秒,而另一个版本需要.027秒。我错过什么了吗?
      C                | C++11
      ====================================
      fibonacci(30)    | clock()
                       | fibonacci(30)
                       | clock()
    
    #include <ctime>
    #include <chrono>
    
    int main()
    {
        for (size_t i = 0; i < 20000; i++)
    #ifdef CSTYLE
            clock();
    #else
            std::chrono::system_clock::now();
    #endif
    }
    
    g++ -std=c++11 -O2 -Wall -pedantic main.cpp && time ./a.out &&
    g++ -std=c++11 -O2 -Wall -pedantic -DCSTYLE main.cpp && time ./a.out
    real  0m0.027s
    user  0m0.008s
    sys   0m0.016s
    
    real  0m0.038s
    user  0m0.000s
    sys   0m0.036s