C++ 衡量std::function的性能成本
我试图衡量std::function与C-function指针的性能成本。我想知道我的测量技术是否对这两种功能都公平(分贝,见下文) 为了测试以下测量值,我重新编译了n1到6的程序(见下文),并切换了带注释的std::function和raw function指针 代码:C++ 衡量std::function的性能成本,c++,performance,c++11,C++,Performance,C++11,我试图衡量std::function与C-function指针的性能成本。我想知道我的测量技术是否对这两种功能都公平(分贝,见下文) 为了测试以下测量值,我重新编译了n1到6的程序(见下文),并切换了带注释的std::function和raw function指针 代码: #包括 #包括 typedef float(*twoArgFuncPtr)(float,float); //函数名和签名 typedef float(*twoArgFuncPtr)(float,float); //与typed
#包括
#包括
typedef float(*twoArgFuncPtr)(float,float);
//函数名和签名
typedef float(*twoArgFuncPtr)(float,float);
//与typedef函数的签名匹配的函数
浮动分贝(浮动p1、浮动p2)
{
返回(浮动)日志(p2/p1);
}
int main()
{
typedef std::chrono::高分辨率时钟高分辨率时钟;
typedef std::chrono::毫秒;
twoArgFuncPtr fnc=分贝;
std::函数fncObj=分贝;
const int numLoops=1000000*1;//重新编译1000000*to N=6
高分辨率时钟::时间点开始=高分辨率时钟::现在();
浮动结果=0;
对于(inti=1,j=numLoops;i std::cout优化后的版本对std::function
非常公平
std::function
典型的实现是一个类型擦除的pImpl内部类,它有一个虚拟的
调用和复制接口
这意味着调用std::function
的成本大约是virtual
方法调用的成本加上原始调用的成本
理论上,std::function
可以优化指向相同签名函数大小写的指针(以及用于包装函数指针的tyoe转换的函数指针指向函数指针大小写)
如果std::function
的virtual
方法表不在缓存中,则会对std::function产生额外的重大影响。这不太可能在您的测试中发生,但在实际的使用案例中很有可能发生。因此,这是非常公平的。我与g++和clang++的区别要小得多。最多约10%。您是否打开了opti优化?顺便说一句,将代码封装在函数模板中的main中,这样您就可以在main中运行两个测试,而无需编辑和重新编译。我关闭了计时的优化(请参阅编辑)。如果打开它们,平均速度会快1.33倍。一般来说,以优化结果为准。未优化代码的速度较低(但不完全是联合国)有趣的是。这两种情况都使优化器可以合理地认识到,fnc
和fncObj
总是指向分贝
,只需直接调用分贝
。如果发生这种情况,您将测量一些与函数指针和std::function的典型用法截然不同的东西代码>。
#include<iostream>
#include<thread>
typedef float (*twoArgFuncPtr)(float, float);
//function name and signature
typedef float (*twoArgFuncPtr)(float, float);
//a function matching the signature of the typedef function
float decibels(float p1, float p2)
{
return (float)log(p2 / p1);
}
int main()
{
typedef std::chrono::high_resolution_clock high_resolution_clock;
typedef std::chrono::milliseconds milliseconds;
twoArgFuncPtr fnc= decibels;
std::function<float(float,float)> fncObj= decibels;
const int numLoops= 1000000*1; //re-compiled for 1000000 * to N=6
high_resolution_clock::time_point start= high_resolution_clock::now();
float result=0;
for(int i=1, j=numLoops; i < numLoops-1; i++, j--)
{
//toggle the comment between the next two lines
result+= fnc((float)i, (float)j); //call by raw ptr
//result+= fncObj((float)i, (float)j); //call by obj //uncomment this line to test std::function
}
high_resolution_clock::time_point end= high_resolution_clock::now();
std::cout<<"Time in seconds: "<<std::chrono::duration_cast<milliseconds>(end-start).count()<<std::endl;
std::cout<<"Result: "<<result<<std::endl;
return 0;
}