Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 衡量std::function的性能成本_C++_Performance_C++11 - Fatal编程技术网

C++ 衡量std::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

我试图衡量std::function与C-function指针的性能成本。我想知道我的测量技术是否对这两种功能都公平(分贝,见下文)

为了测试以下测量值,我重新编译了n1到6的程序(见下文),并切换了带注释的std::function和raw function指针

代码:

#包括
#包括
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;istd::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;
}