title: Returning std::pair versus passing by non-const reference
body: <p>Why is returning a <code>std::pair</code> or <code>boost::tuple</code> so much less efficient than returning by reference? In real codes that I've tested, setting data by non-const reference rather than by <code>std::pair</code> in an inner kernel can speed up the code by 20%.</p>
  
  <p>As an experiment, I looked at three simplest-case scenarios involving adding two (predefined) integers to two integers:</p>
  
  <ol>
  <li><p>Use an inner, inlined function to modify the integers by reference</p></li>
  <li><p>Use two inner, inlined function to return ints by value</p></li>
  <li><p>Use an inner, inlined function to return a std::pair which are copied to the result.</p></li>
  </ol>
  
  <p>Compiling with <code>g++ -c $x -Wall -Wextra -O2 -S</code> results in the same assembly code for passing by reference and returning ints by value:</p>
  
  <pre><code>__Z7getPairiRiS_:
  LFB19:
      pushq   %rbp
  LCFI0:
      leal    1023(%rdi), %eax
      addl    $31, %edi
      movl    %eax, (%rsi)
      movq    %rsp, %rbp
  LCFI1:
      movl    %edi, (%rdx)
      leave
      ret
  </code></pre>
  
  <p>(Pass by reference code:</p>
  
  <pre><code>#include &lt;utility&gt;
  
  inline void myGetPair(const int inp, int&amp; a, int&amp; b) {
      a = 1023 + inp;
      b = 31 + inp;
  }
  
  void getPair(const int inp, int&amp; a, int&amp; b) {
      myGetPair(inp, a, b);
  }
  </code></pre>
  
  <p>Using individual rvalues:</p>
  
  <pre><code>#include &lt;utility&gt;
  
  inline int myGetPair1(int inp) {
      return 1023 + inp;
  }
  
  inline int myGetPair2(int inp) {
      return 31 + inp;
  }
  
  void getPair(const int inp, int&amp; a, int&amp; b) {
      a = myGetPair1(inp);
      b = myGetPair2(inp);
  }
  </code></pre>
  
  <p>)</p>
  
  <p>Using std::pair, however, adds five extra assembly statements:</p>
  
  <pre><code>__Z7getPairiRiS_:
  LFB18:
      leal    31(%rdi), %eax
      addl    $1023, %edi
      pushq   %rbp
  LCFI0:
      salq    $32, %rax
      movq    %rsp, %rbp
  LCFI1:
      orq %rdi, %rax
      movq    %rax, %rcx
      movl    %eax, (%rsi)
      shrq    $32, %rcx
      movl    %ecx, (%rdx)
      leave
      ret
  </code></pre>
  
  <p>The code for that is nearly as simple as the previous examples:</p>
  
  <pre><code>#include &lt;utility&gt;
  
  inline std::pair&lt;int,int&gt; myGetPair(int inp) {
      return std::make_pair(1023 + inp, 31 + inp);
  }
  
  void getPair(const int inp, int&amp; a, int&amp; b) {
      std::pair&lt;int,int&gt; result = myGetPair(inp);
  
      a = result.first;
      b = result.second;
  }
  </code></pre>
  
  <p>Can anyone who knows the inner workings of compilers help with this question? The <a href="http://www.boost.org/doc/libs/1_41_0/libs/tuple/doc/tuple_users_guide.html" rel="nofollow noreferrer">boost tuple page</a> makes reference to a performance penalty for tuples vs. pass-by-reference, but none of the linked papers answer the question.</p>
  
  <p>The reason I'd prefer std::pair to these pass-by-reference statements is that it makes the intent of the function <em>much</em> clearer in many circumstances, especially when other parameters are input as well as the ones that are to be modified.</p>