C++ CRTP和虚函数开销方法调用
如何使用CRTP防止函数调用开销?这些类的详细信息是开放的,但我基本上有一个基类a和一些从a继承的其他类,但实现了一个从a调用的专用函数。从a继承的类有一个专用函数,可以重复多次(见下文)。在我的基准测试中,CRTP实现与CRTP实现一样快,但比平面类实现慢,即没有继承。这怎么可能?最初,我用虚拟函数解决了这个问题,如下所示:C++ CRTP和虚函数开销方法调用,c++,virtual-functions,crtp,C++,Virtual Functions,Crtp,如何使用CRTP防止函数调用开销?这些类的详细信息是开放的,但我基本上有一个基类a和一些从a继承的其他类,但实现了一个从a调用的专用函数。从a继承的类有一个专用函数,可以重复多次(见下文)。在我的基准测试中,CRTP实现与CRTP实现一样快,但比平面类实现慢,即没有继承。这怎么可能?最初,我用虚拟函数解决了这个问题,如下所示: // VIRTUAL EXAMPLE class VIRTUAL_A{ public: virtual void do_inner() {}; void d
// VIRTUAL EXAMPLE
class VIRTUAL_A{
public:
virtual void do_inner() {};
void do_stuff(size_t N){
for (size_t i = 0; i<N ; i++){
this->do_inner();
}
}
};
class VIRTUAL_B : public VIRTUAL_A{
public:
void do_inner() override{
//do heavy computation
}
};
//虚拟示例
类虚拟_A{
公众:
虚空do_internal(){};
作废待办事项(尺寸){
对于(size_t i=0;ido_inner();
}
}
};
虚拟课程B:公共虚拟课程A{
公众:
void do_internal()重写{
//做繁重的计算
}
};
然后我将其翻译为CRTP:
// CRTP EXAMPLE
template <template T>
class CRTP_A{
public:
void do_stuff(size_t N){
for (size_t i = 0; i<N ; i++){
static_cast<T&>(*this).do_inner();
}
}
};
class CRTP_B : public CRTP_A<CRTP_B>{
void do_inner(){
// heavy computation
}
};
//CRTP示例
模板
类别CRTP_A{
公众:
作废待办事项(尺寸){
对于(size_t i=0;ido_inner();
}
}
};
(省略课堂细节)实际基准分数:
对于任意测试用例,数字以秒为单位。差值作为N的函数是一致的
现在我的问题是:
- CRTP中是否存在运行时函数调用的开销
- 我是否在初始化类时遗漏了某些内容,以致编译器无法在CRTP方法中内联派生类
谢谢!如果看不到精确的基准测试和编译后的程序集,很难说。你确定编译器没有优化(例如循环)吗?这有点复杂,因为整个代码库都是用cython编写的,我目前正在探索将其翻译成cpp。我不是cpp方面的专家,但可以在这里找到反汇编代码()。使用CRPT的相关“重载”功能位于地址(0x25750)@Quimby在帖子中添加了汇编中的相关扇区。所有三个输出都不同,虚拟调用是最大的。与flat类相比,CRTP函数中增加了4行。我不知道如何进一步解释它,你有什么想法吗?
// FLAT EXAMPLE
class FLAT_A{
public:
void do_inner(){
//heavy computation
}
void do_stuff(size_t N){
for (size_t i = 0 ; i < N ; i++ ){
this->do_inner();
}
}
};