【问题标题】:Inlining an overloaded operator c++内联重载运算符 C++
【发布时间】:2011-09-22 20:54:50
【问题描述】:

如果必须经常使用重载的运算符,是否可以/是否必须内联重载运算符以获得更好的效率(wrt time 或其他)?

我想重载“+”运算符,以便在我的代码中非常频繁地添加大向量。因此问题。

【问题讨论】:

    标签: c++ overloading


    【解决方案1】:

    理想情况下,您会分析您的代码,然后决定内联的内容。决定内联常规运算符和重载运算符之间确实没有太大区别。

    【讨论】:

    • +1。还有@Gaurish Telang:内联适配器方法是合乎逻辑的(为兼容性而提供的方法,例如,它调用具有相同参数的其他方法)。
    • +1。在我们工作的团队中,我们的编码标准不鼓励在头文件中内联方法,除非有可证明的性能提升。我们也不鼓励数学运算符的运算符重载,除非类本身在逻辑上可以被认为是一个数字。
    • +1 to @selbie:在大多数情况下,运算符重载只会掩盖代码的逻辑。
    【解决方案2】:

    如果您要添加大向量,那么相对于实际添加两个向量的时间而言,对 plus 的函数调用的开销会很小。因此,将 operator+ 标记为内联不太可能提高您的整体运行时间。

    【讨论】:

    • ...或者至少不够在意。
    • 如果操作符被频繁使用,内联会增加代码量,并可能由于缓存未命中而降低效率。
    【解决方案3】:

    让编译器决定优化。

    关键字inline 具有误导性:编译器可以——事实上——总是做它需要做的事情,就像 auto(你还记得那些日子吗?)和@987654323 @。

    它的现代含义是“在标题中定义:如果不使用则丢弃,如果看到更多次则合并”。

    【讨论】:

      【解决方案4】:

      编译器应该在发布版本中自动为您内联小的函数。 更重要的是定义移动构造函数和移动赋值。如果您的数组非常大,并且您同时进行多项操作,您还可以使用表达式类来提高执行速度。

      template <class left, class right>
      struct AddExpr { 
          const left& _left;
          const right& _right;
      
          AddExpr(const left& Left, const right& Right)
          :_left(Left), _right(Right)
          {assert(left.count() == right.count());}
          int count() const {return _left.count();}
          int operator[](int index) const {return _left[i]+_right[i];}
      };
      class Array {
          int* data;
          int size;
      
          int count() const {return size;}
          Array& operator=(AddExpr expr) {
              for(int i=0; i<expr.count(); ++i)
                 data[i] = expr[i];
      };
      AddExpr operator+(const Array& lhs, const Array& rhs) 
      {return AddExpr<Array, Array>(lhs, rhs);}
      AddExpr operator+(const Array& lhs, const Expr& rhs) 
      {return AddExpr<Array, Expr>(lhs, rhs);}
      AddExpr operator+(const Expr& lhs, const Array& rhs) 
      {return AddExpr<Expr, Array>(lhs, rhs);}
      AddExpr operator+(const Expr& lhs, const Expr& rhs) 
      {return AddExpr<Expr, Expr>(lhs, rhs);}
      
      int main() {
          Array a, b, c, d;
          Array c = (a+b) + (c+d);  //awesome on lines like this
      }
      

      这会移除所有的临时对象,大大提高缓存效率。但是我完全忘记了这种技术叫什么。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-29
        • 2016-02-19
        相关资源
        最近更新 更多