title: Splitting header and implementation causes significant slow-down
body: <p>When I split the header and implementation in c++, I found that significant slow-down occurs in some situation compared to the header-only one. The minumum working example is like below. In the case below, <code>get_sum</code> function is implemented in the header file and <code>get_sum2</code>, which is exactly the same implementation as <code>get_sum</code>, is implemented in <code>impl.cpp</code>. The result shows that time duration to execute is 0.001 [msec] for <code>get_sum</code> and 1066.84 [msec] for <code>get_sum2</code> (see <code>main.cpp</code>), though both have the same implementation. Could anyone explain why this happens?</p>
  <p>The following codes can be found <a href="https://github.com/HiroIshida/snippets/tree/master/cpp/perf_impl_split" rel="nofollow noreferrer">here</a>.</p>
  <p>The header file <code>header.h</code></p>
  <pre class="lang-cpp prettyprint-override"><code>#include&lt;vector&gt;
  #include&lt;iostream&gt;
  
  using namespace std;
  class Tester
  {
    public:
      Tester(int n){ 
        table_.resize(n);
        for(int i=0; i&lt;n; i++){
          table_[i].resize(n);
        }
      }
  
      bool get_sum(){
        double s = 0;
        for(auto&amp; subtable : table_){
          for(double e : subtable){
            s += e;
          }
        }
        return s;
      }
      bool get_sum2(); // definition is in impl.cpp
    private:
      vector&lt;vector&lt;double&gt;&gt; table_;
  };
  
  </code></pre>
  <p>The implementation file <code>impl.cpp</code></p>
  <pre class="lang-cpp prettyprint-override"><code>bool Tester::get_sum2(){
    double s = 0;
    for(auto&amp; subtable : table_){
      for(double e : subtable){
        s += e;
      }
    }
    return s;
  }
  </code></pre>
  <p>The main file for benchmarking <code>main.cpp</code></p>
  <pre class="lang-cpp prettyprint-override"><code>#include &quot;header.h&quot;
  int main(){
    int size = 30000;
    auto tester = Tester(size);
    std::cout &lt;&lt; &quot;Finish constructing the tester&quot; &lt;&lt; std::endl; 
    {
      clock_t start = clock();
      tester.get_sum();
      clock_t end = clock();
      std::cout &lt;&lt; (end - start)/1000.0 &lt;&lt; &quot; [msec]&quot; &lt;&lt; std::endl; 
    }
  
    {
      clock_t start = clock();
      tester.get_sum2();
      clock_t end = clock();
      std::cout &lt;&lt; (end - start)/1000.0 &lt;&lt; &quot; [msec]&quot; &lt;&lt; std::endl; 
    }
  }
  </code></pre>
  <p>The output of execution of <code>main.cpp</code> is</p>
  <pre><code>Finish constructing the tester
  0.001 [msec]
  1054.71 [msec]
  </code></pre>
  <p>cmake script used <code>CmakeLists.txt</code> (note that build with release mode)</p>
  <pre><code>cmake_minimum_required(VERSION 3.4 FATAL_ERROR)
  set(CMAKE_BUILD_TYPE Release)
  add_executable(main main.cpp impl.cpp)
  </code></pre>