constexpr与重复函数调用性能

时间:2019-03-16 13:53:03

标签: c++ performance repeat constexpr

我正在测试以下代码以检查constexpr的性能。对于第一次迭代,结果是预期的。但是对于下一次迭代,普通函数有时会胜过constexpr。我在这里想念什么?我希望constexpr通话在任何情况下都会更好。同样,法线函数花费的时间在第一次迭代后也会减少。如何解释这种行为?

您可以看到代码结果here

  

编辑:如果我取消注释以下代码中的行,这些行提供了每次迭代求和的不同值,则结果仍然相似。您可以查看其结果here

     

Edit2:我尝试了@geza更改,并在第一个函数调用中执行了3百万次操作,在第二个函数调用中执行了3 Million + i。我期望constexpr花费的时间要少得多(几乎与100花费的时间相同),但是它花费的时间却与非constexpr函数一样多。结果link

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

constexpr long long sum(const int* n){
    long long sum = 0;
    for(int i = 1; i <= *n; i++){
        sum += i;
    }
    return sum;
}

long long sum(int*  n){
    cout<<"Calling sum\n";
    long long sum = 0;
    for(int i = 1; i <= *n; i++){
        sum += i;
    }
    return sum;
}


int main(void){
    const int* p;
    int a = 100;
    p = &a;

    int *p1;
    p1 = &a;

    for(int i = 0; i < 10; i++){

        /*
        int* p1;
        int b = 100 + i; //If I uncomment the lines here are remove the 
        p1 = &b;         //earlier p1 declaration. Still the results are similar
        */

        auto start = high_resolution_clock::now(); 
        cout<<sum(p1)<<endl;
        auto stop = high_resolution_clock::now();
        cout<<"Time taken Non constexpr: "<<duration_cast<microseconds>(stop - start).count()<<endl;

        start = high_resolution_clock::now(); 
        cout<<sum(p)<<endl;
        stop = high_resolution_clock::now();
        cout<<"Time taken constexpr: "<<duration_cast<microseconds>(stop - start).count()<<endl;
    }
}

我的代码很简单,创建两个指针,一个是常量(p),另一个不是(p1)。在使用sum()调用p1时,将调用不包含constexpr的函数,该函数可以通过打印“ Calling sum 和在使用{{1}进行调用时看到},将调用带有p的函数,这可以看成是什么都没打印出来。

  

结果

$ g ++ -o main * .cpp
$ main
调用sum
5050
花费时间非constexpr:63
5050
constexpr花费的时间:7

调用sum
5050
花费时间非constexpr:5
5050
constexpr花费的时间:6




电话总和
5050
花费时间非constexpr:2
5050
constexpr花费的时间:6





调用sum
5050
花费时间非constexpr:2
5050
constexpr花费的时间:2

2 个答案:

答案 0 :(得分:2)

您的测量错误。您的时间安排包括打印到stdout。修改程序以正确测量时间(并从cout中删除sum):

auto start = high_resolution_clock::now(); 
auto r = sum(p1);
auto stop = high_resolution_clock::now();
cout<<r<<endl;
cout<<"Time taken Non constexpr: "<<duration_cast<microseconds>(stop - start).count()<<endl;

您会注意到,在几乎所有情况下,时间都是0。

(对原始程序的解释:似乎对cout <<的第一次调用比其他调用花费更多的时间。很可能cout进行了某种推迟的初始化,这就是为什么第一次通话比较慢。)

请注意,由于您不在sum(const int *)上下文中调用constexpr,因此它将像sum(int *)一样用作“常规”函数调用。

答案 1 :(得分:1)

我建议您启用优化,然后重新运行基准测试。 C ++,尤其是库,依赖于编译器优化来生成快速的汇编代码。优化器可以删除库抽象,然后发出更好的代码。

您链接的网站允许您更改编译器选项,只需添加-O2即可设置优化级别2,然后重新运行基准测试。