C++ 虚拟函数调用成本是正常函数调用的1.5倍(带测试用例)

C++ 虚拟函数调用成本是正常函数调用的1.5倍(带测试用例),c++,c++14,vtable,C++,C++14,Vtable,我必须决定是否使用模板还是虚拟继承。 在我的情况下,这让我很难做出选择。 最后,它归结为“虚拟呼叫的实际成本(CPU)是多少?” 我发现很少有资源敢以实际数字衡量vtable成本,例如,指向第26页的 以下是它的摘录:- 然而,(虚拟的)这种开销大约为20%和12%——远低于 编译器之间的可变性 在依赖事实之前,我已经决定亲自测试它 我的测试代码有点长(~40行),您也可以在正在运行的链接中看到它。 该数字是虚拟呼叫使用的时间除以正常呼叫的时间之比。 出乎意料的是,结果与OpenSTD所说的相悖

我必须决定是否使用模板还是虚拟继承。
在我的情况下,这让我很难做出选择。
最后,它归结为“虚拟呼叫的实际成本(CPU)是多少?”

我发现很少有资源敢以实际数字衡量vtable成本,例如,指向第26页的

以下是它的摘录:-

然而,(虚拟的)这种开销大约为20%12%——远低于 编译器之间的可变性

在依赖事实之前,我已经决定亲自测试它

我的测试代码有点长(~40行),您也可以在正在运行的链接中看到它。
该数字是虚拟呼叫使用的时间除以正常呼叫的时间之比。
出乎意料的是,结果与OpenSTD所说的相悖

  • 1.58
  • (使用自定义氧气):1.89
  • 2.79
  • <我的台式电脑(Visual C++,-O2):在<>强> 1.5 < /强>
这是:-

#include <iostream>
#include <chrono>
#include <vector>
using namespace std;
class B2{
        public: int randomNumber=((double) rand() / (RAND_MAX))*10;
        virtual ~B2() = default;
        virtual int f(int n){return -n+randomNumber;}
        int g(int n){return -n+randomNumber;}
};
class C : public B2{
    public: int f(int n) override {return n-randomNumber;}
};
int main() {
    std::vector<B2*> bs;
    const int numTest=1000000;
    for(int n=0;n<numTest;n++){
        if(((double) rand() / (RAND_MAX))>0.5){
            bs.push_back(new B2());
        }else{
            bs.push_back(new C());
        }
    };
    auto t1 = std::chrono::system_clock::now();
    int s=0;
    for(int n=0;n<numTest;n++){ 
        s+=bs[n]->f(n);
    };
    auto t2= std::chrono::system_clock::now();
    for(int n=0;n<numTest;n++){
        s+=bs[n]->g(n);
    };
    auto t3= std::chrono::system_clock::now();
    auto t21=t2-t1;
    auto t32=t3-t2;
    std::cout<<t21.count()<<" "<<t32.count()<<" ratio="<< (((float)t21.count())/t32.count()) << std::endl;
    std::cout<<s<<std::endl;
    for(int n=0;n<numTest;n++){
        delete bs[n];
    };
}
#包括
#包括
#包括
使用名称空间std;
B2类{
public:int randomNumber=((双)rand()/(rand_MAX))*10;
virtual~B2()=默认值;
虚int f(int n){return-n+randomNumber;}
int g(int n){return-n+randomNumber;}
};
C类:公共B2{
public:intf(intn)重写{返回n-randomNumber;}
};
int main(){
std::向量bs;
常数int numTest=1000000;
对于(int n=0;n0.5){
bs.推回(新B2());
}否则{
b.推回(新C());
}
};
自动t1=std::chrono::system_clock::now();
int s=0;
对于(int n=0;nf(n);
};
自动t2=std::chrono::system_clock::now();
对于(int n=0;ng(n);
};
自动t3=std::chrono::system_clock::now();
自动t21=t2-t1;
自动t32=t3-t2;

std::cout.另外,虽然虚拟函数比非虚拟函数慢,但调用虚拟函数的代码所占的百分比是多少?换句话说,如果95%的代码都在做非虚拟的事情,而只有95%的代码在进行虚拟函数调用,并且虚拟函数调用的速度是非虚拟函数调用的1.5倍,那么您的代码运行速度只慢1.025倍虚拟函数比没有好。@gman我理解你的意思是“过早优化是邪恶的”。换句话说,我可能不会从这部分的优化中获得太多。但是,在这个问题的范围内,我仍然想知道它。另外,虽然虚拟函数比非虚拟函数慢,但有多少百分比的代码调用虚拟函数?换句话说,如果95%的代码做非虚拟的事情,只有95%的代码调用虚拟函数e正在进行虚拟函数调用,而虚拟函数调用的速度是虚拟函数调用速度的1.5倍,那么使用虚拟函数时代码的运行速度只比不使用虚拟函数时慢1.025倍。@gman我理解你的意思是“过早优化是邪恶的”.换句话说,我可能不会从这部分的优化中获得太多。但是,在这个问题的范围内,我仍然想知道它。