title: c++ overloaded parentheses operator slower than direct access to array member
body: <p>At the moment I am trying to figure out why my naive matrix-matrix-multiplication is slower (0.7 sec) when I use the overloaded parentheses operator (<code>//first multiplication</code>). If I don't use them (<code>//second multiplication</code>) and the multiplication directly access the class member array <code>data_</code> it is about twice as fast (0.35 sec). I use my own matrix class as defined in <code>Matrix.h</code>. </p>
  
  <p>Why is there such a significant difference in speed? Is there something wrong with my copy constructor? Is there so much "overhead" in calling the overloaded operator function that it justifies for that kind of performance penalty?</p>
  
  <p>There is one more question / weird behavior: When you exchange the two inner most loops (<code>x</code> and <code>inner</code>) with each other, then the multiplication gets (of course) really slow, but both multiplications take almost the SAME time (7 sec) now. Why does it take the same time for them in this case, but before there was a ~50% performance difference.</p>
  
  <p>edit: The program is compiled the following way: <code>g++ -c -std=c++0x -O3 -DNDEBUG</code></p>
  
  <p>Thank you so much for your help!</p>
  
  <p>My main function looks like this:</p>
  
  <pre><code>#include "Matrix.h"
  int main(){
      Matrix m1(1024,1024, 2.0);
      Matrix m2(1024,1024, 2.5);
      Matrix m3(1024,1024);
  
      //first multiplication
      for(int y = 0; y &lt; 1024; ++y){
          for(int inner = 0; inner &lt; 1024; ++inner){
              for(int x = 0; x &lt; 1024; ++x){
                  m3(y,x) += m1(y, inner) * m2(inner, x);
              }
          }
      }
  
      //second multiplication
      for(int y = 0; y &lt; 1024; ++y){
          for(int inner = 0; inner &lt; 1024; ++inner){
              for(int x = 0; x &lt; 1024; ++x){
                  m3.data_[y*1024+x] += m1.data_[y*1024+inner]*m2.data_[inner*1024+inner];
              }
          }
      }
  }
  </code></pre>
  
  <p>And here is the part of <code>Matrix.h</code>:</p>
  
  <pre><code>class Matrix{
  
  public:
      Matrix();
      Matrix(int sizeY, int sizeX);
      Matrix(int sizeY, int sizeX, double init);
      Matrix(const Matrix &amp; orig);
      ~Matrix(){delete[] data_;}
      double &amp; operator() (int y, int x);
      double operator() (int y, int x) const;
  
      double * data_;
  
  private:    
      int sizeX_;
      int sizeY_;
  
  }
  </code></pre>
  
  <p>And here the Implementation of <code>Matrix.h</code></p>
  
  <pre><code>Matrix::Matrix()
      : sizeX_(0),
      sizeY_(0),
      data_(nullptr)
  { }
  
  Matrix::Matrix(int sizeY, int sizeX)
      : sizeX_(sizeX),
      sizeY_(sizeY),
      data_(new double[sizeX*sizeY]())
  {
      assert( sizeX &gt; 0 );
      assert( sizeY &gt; 0 );
  }
  
  Matrix::Matrix(int sizeY, int sizeX, double init)
      : sizeX_(sizeX), 
      sizeY_(sizeY)
  {   
      assert( sizeX &gt; 0 );
      assert( sizeY &gt; 0 );
      data_ = new double[sizeX*sizeY];
      std::fill(data_, data_+(sizeX_*sizeY_), init);
  }
  
  Matrix::Matrix(const Matrix &amp; orig)
      : sizeX_(orig.sizeX_),
      sizeY_(orig.sizeY_)
  {
      data_ = new double[orig.sizeY_*orig.sizeX_];
      std::copy(orig.data_, orig.data_+(sizeX_*sizeY_), data_);
  }
  
  
  double &amp; Matrix::operator() (int y, int x){
      assert( x &gt;= 0 &amp;&amp; x &lt; sizeX_);
      assert( y &gt;= 0 &amp;&amp; y &lt; sizeY_);
      return data_[y*sizeX_ + x];
  }
  
  double Matrix::operator() (int y, int x) const {
      assert( x &gt;= 0 &amp;&amp; x &lt; sizeX_);
      assert( y &gt;= 0 &amp;&amp; y &lt; sizeY_);
      return data_[y*sizeX_ + x];
  }
  </code></pre>
  
  <p><strong>EDIT2:</strong> Turns out I used the wrong array access for the <code>//second multiplication</code>. I changed it to <code>m3.data_[y*1024+x] += m1.data_[y*1024+inner]*m2.data_[inner*1024+x];</code> and now both multiplications take the same time.
  Thank you very much for your help!</p>