我正在测试下面的代码来检查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
的函数被调用,这可以通过打印“调用sum并且在使用p
调用时看到,constexpr
的函数被调用,可以看作没有打印。
结果
$ g ++ -o main * .cpp $主 打电话 5050 所用时间非constexpr:63 5050 constexpr所花费的时间:7 打电话 5050 所用时间非constexpr:5 5050 constexpr采取的时间:6 。 。 。 。 打电话 5050 所用时间非constexpr:2 5050 constexpr采取的时间:6 。 。 。 。 打电话 5050 所用时间非constexpr:2 5050 时间采用constexpr:2
我建议您启用优化,然后重新运行基准测试。 C ++,尤其是库,依赖于编译器优化来生成快速汇编代码。优化器可以剥离库抽象,然后发出更好的代码。
您链接的网站允许您更改编译器选项,只需添加-O2
即可设置优化级别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 *)
一样。