Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.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++ CRTP和虚函数开销方法调用_C++_Virtual Functions_Crtp - Fatal编程技术网

C++ 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

如何使用CRTP防止函数调用开销?这些类的详细信息是开放的,但我基本上有一个基类a和一些从a继承的其他类,但实现了一个从a调用的专用函数。从a继承的类有一个专用函数,可以重复多次(见下文)。在我的基准测试中,CRTP实现与CRTP实现一样快,但比平面类实现慢,即没有继承。这怎么可能?最初,我用虚拟函数解决了这个问题,如下所示:

// 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方法中内联派生类
编辑:: 装配输出

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();
    }
  }

};