constexpr vs 重复函数调用性能
constexpr vs repeated function calls performance
我正在测试下面的代码来检查 constexpr
的性能。对于第一次迭代,结果符合预期。但是对于下一次迭代,正常函数调用有时会优于 constexpr
。我在这里错过了什么?我希望 constexpr
调用在任何情况下都更好。此外,正常功能所花费的时间在第一次迭代后也会减少。如何解释这种行为?
可以看到代码结果here
Edit: If I un-comment the lines in the below code providing different values to sum for each iteration, still the results are similar. You can see its results here
Edit2: I tried @geza changes and performed the operation for 3 Million for the first function call and with 3 Million + i
for the second function call. I was expecting the constexpr to take very less time(almost same as the time taken with 100) but its taking as much time as the non-constexpr function. Results 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
)。在使用 p1
调用 sum()
时,调用了没有 constexpr
的函数,这可以通过打印 "Calling sum 和使用 p
, 函数 constexpr
被调用,可以看出没有打印任何内容。
Results
$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
你的测量有误。您的时间包括打印到 stdout
。修改您的程序以正确测量时间(并从 sum
中删除 cout
):
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
进行了某种延迟初始化,这就是第一次调用较慢的原因。)
请注意,由于您不在 constexpr
上下文中调用 sum(const int *)
,它将用作 "normal" 函数调用,就像 sum(int *)
一样。
我建议您启用优化,然后重新运行您的基准测试。 C++,尤其是库,依赖于编译器优化来生成快速的汇编代码。优化器可以剥离库抽象,然后发出更好的代码。
您链接的网站允许您更改编译器选项,只需添加 -O2
以设置优化级别 2 并重新运行基准测试。
我正在测试下面的代码来检查 constexpr
的性能。对于第一次迭代,结果符合预期。但是对于下一次迭代,正常函数调用有时会优于 constexpr
。我在这里错过了什么?我希望 constexpr
调用在任何情况下都更好。此外,正常功能所花费的时间在第一次迭代后也会减少。如何解释这种行为?
可以看到代码结果here
Edit: If I un-comment the lines in the below code providing different values to sum for each iteration, still the results are similar. You can see its results here
Edit2: I tried @geza changes and performed the operation for 3 Million for the first function call and with
3 Million + i
for the second function call. I was expecting the constexpr to take very less time(almost same as the time taken with 100) but its taking as much time as the non-constexpr function. Results 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
)。在使用 p1
调用 sum()
时,调用了没有 constexpr
的函数,这可以通过打印 "Calling sum 和使用 p
, 函数 constexpr
被调用,可以看出没有打印任何内容。
Results
$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
你的测量有误。您的时间包括打印到 stdout
。修改您的程序以正确测量时间(并从 sum
中删除 cout
):
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
进行了某种延迟初始化,这就是第一次调用较慢的原因。)
请注意,由于您不在 constexpr
上下文中调用 sum(const int *)
,它将用作 "normal" 函数调用,就像 sum(int *)
一样。
我建议您启用优化,然后重新运行您的基准测试。 C++,尤其是库,依赖于编译器优化来生成快速的汇编代码。优化器可以剥离库抽象,然后发出更好的代码。
您链接的网站允许您更改编译器选项,只需添加 -O2
以设置优化级别 2 并重新运行基准测试。