title: boost::variant vs. polymorphism, very different performance results with clang and gcc
body: <p>I'm trying to figure out how much the execution time of boost::variant differ from a polymorphism approach. In my first test I got very different results on gcc 4.9.1 and clang+llvm 3.5.</p>
  <p>You can find the code below. Here are my results:</p>
  <h3>clang+llvm</h3>
  <pre><code>polymorphism: 2.16401
  boost::variant: 3.83487
  </code></pre>
  
  <h3>gcc:</h3>
  <pre><code>polymorphism: 2.46161
  boost::variant: 1.33326
  </code></pre>
  <p>I compiled both with -O3.
  Is someone able to explain that?</p>
  <h3>code</h3>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;vector&gt;
  #include &lt;algorithm&gt;
  #include &lt;boost/variant.hpp&gt;
  #include &lt;boost/variant/apply_visitor.hpp&gt;
  #include &lt;ctime&gt;
  
  struct value_type {
  
      value_type() {}
      virtual ~value_type() {}
      virtual void inc() = 0;
  };
  
  struct int_type : value_type {
  
      int_type() : value_type() {}
      virtual ~int_type() {}
  
      void inc() { value += 1; }
  
        private:
      int value = 0;
  };
  
  struct float_type : value_type {
  
      float_type() : value_type() {}
      virtual ~float_type() {}
  
      void inc() { value += 1; }
  
        private:
      float value = 0;
  };
  
  void dyn_test() {
  
      std::vector&lt;std::unique_ptr&lt;value_type&gt;&gt; v;
      for (int i = 0; i &lt; 1024; i++) {
          if (i % 2 == 0)
              v.emplace_back(new int_type());
          else
              v.emplace_back(new float_type());
      }
  
      for (int i = 0; i &lt; 900000; i++) {
          std::for_each(v.begin(), v.end(), [](auto &amp;item) { item-&gt;inc(); });
      }
  }
  
  struct visitor : boost::static_visitor&lt;&gt; {
  
      template &lt;typename T&gt; void operator()(T &amp;item) { item += 1; }
  };
  
  using mytype = boost::variant&lt;int, float&gt;;
  void static_test() {
      std::vector&lt;mytype&gt; v;
      for (int i = 0; i &lt; 1024; i++) {
          if (i % 2 == 0)
              v.emplace_back(0);
          else
              v.emplace_back(0.f);
      }
  
      visitor vi;
      for (int i = 0; i &lt; 900000; i++) {
          std::for_each(v.begin(), v.end(), boost::apply_visitor(vi));
      }
  }
  
  template &lt;typename F&gt; double measure(F f) {
      clock_t start = clock();
      f();
      clock_t end = clock();
      float seconds = (float)(end - start) / CLOCKS_PER_SEC;
      return seconds;
  }
  
  int main() {
      std::cout &lt;&lt; &quot;polymorphism: &quot; &lt;&lt; measure([] { dyn_test(); }) &lt;&lt; std::endl;
      std::cout &lt;&lt; &quot;boost::variant: &quot; &lt;&lt; measure([] { static_test(); }) &lt;&lt; std::endl;
  
      return 0;
  }    
  </code></pre>
  <h3>assembler</h3>
  <p><a href="http://pastebin.com/bBTk18LB" rel="nofollow noreferrer">gcc</a></p>
  <p><a href="http://pastebin.com/A7xWsf5k" rel="nofollow noreferrer">clang+llvm</a></p>