title: Why is std::string_view faster than const char*?
body: <p>Or am I measuring something else?</p>
  
  <p>In this code I have a stack of tags (<code>integers</code>). Each tag has a string representation (<code>const char*</code> or <code>std::string_view</code>).
  In the loop stack values are converted to the corresponding string values. Those values are appended to a preallocated string or assigned to an array element.</p>
  
  <p>The results show that the version with <code>std::string_view</code> is slightly faster than the version with <code>const char*</code>.</p>
  
  <p>Code:</p>
  
  <pre class="lang-cpp prettyprint-override"><code>#include &lt;array&gt;
  #include &lt;iostream&gt;
  #include &lt;chrono&gt;
  #include &lt;stack&gt;
  #include &lt;string_view&gt;
  
  using namespace std;
  
  int main()
  {
      enum Tag : int { TAG_A, TAG_B, TAG_C, TAG_D, TAG_E, TAG_F };
      constexpr const char* tag_value[] = 
          { "AAA", "BBB", "CCC", "DDD", "EEE", "FFF" };
      constexpr std::string_view tag_values[] =
          { "AAA", "BBB", "CCC", "DDD", "EEE", "FFF" };
  
      const size_t iterations = 10000;
      std::stack&lt;Tag&gt; stack_tag;
      std::string out;
      std::chrono::steady_clock::time_point begin;
      std::chrono::steady_clock::time_point end;
  
      auto prepareForBecnhmark = [&amp;stack_tag, &amp;out](){
          for(size_t i=0; i&lt;iterations; i++)
              stack_tag.push(static_cast&lt;Tag&gt;(i%6));
          out.clear();
          out.reserve(iterations*10);
      };
  
  // Append to string
      prepareForBecnhmark();
      begin = std::chrono::steady_clock::now();
      for(size_t i=0; i&lt;iterations; i++) {
          out.append(tag_value[stack_tag.top()]);
          stack_tag.pop();
      }
      end = std::chrono::steady_clock::now();
      std::cout &lt;&lt; out[100] &lt;&lt; "append string const char* = " &lt;&lt; std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - begin).count() &lt;&lt; "[µs]" &lt;&lt; std::endl;
  
      prepareForBecnhmark();
      begin = std::chrono::steady_clock::now();
      for(size_t i=0; i&lt;iterations; i++) {
          out.append(tag_values[stack_tag.top()]);
          stack_tag.pop();
      }
      end = std::chrono::steady_clock::now();
      std::cout &lt;&lt; out[100] &lt;&lt; "append string string_view= " &lt;&lt; std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - begin).count() &lt;&lt; "[µs]" &lt;&lt; std::endl;
  
  // Add to array
      prepareForBecnhmark();
      std::array&lt;const char*, iterations&gt; cca;
      begin = std::chrono::steady_clock::now();
      for(size_t i=0; i&lt;iterations; i++) {
          cca[i] = tag_value[stack_tag.top()];
          stack_tag.pop();
      }
      end = std::chrono::steady_clock::now();
      std::cout &lt;&lt; "fill array const char* = " &lt;&lt; std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - begin).count() &lt;&lt; "[µs]" &lt;&lt; std::endl;
  
      prepareForBecnhmark();
      std::array&lt;std::string_view, iterations&gt; ccsv;
      begin = std::chrono::steady_clock::now();
      for(size_t i=0; i&lt;iterations; i++) {
          ccsv[i] = tag_values[stack_tag.top()];
          stack_tag.pop();
      }
      end = std::chrono::steady_clock::now();
      std::cout &lt;&lt; "fill array string_view = " &lt;&lt; std::chrono::duration_cast&lt;std::chrono::microseconds&gt;(end - begin).count() &lt;&lt; "[µs]" &lt;&lt; std::endl;
      std::cout &lt;&lt; ccsv[ccsv.size()-1] &lt;&lt; cca[cca.size()-1] &lt;&lt; std::endl;
  
      return 0;
  }
  </code></pre>
  
  <p>Results on my machine are:</p>
  
  <pre><code>Aappend string const char* = 97[µs]
  Aappend string string_view= 72[µs]
  fill array const char* = 35[µs]
  fill array string_view = 18[µs]
  </code></pre>
  
  <p>Godbolt compiler explorer url: <a href="https://godbolt.org/z/SMrevx" rel="nofollow noreferrer">https://godbolt.org/z/SMrevx</a></p>
  
  <p><strong>UPD:</strong> Results after more accurate benchmarking (500 runs 300000 iterations):</p>
  
  <pre><code>Caverage append string const char* = 2636[µs]
  Caverage append string string_view= 2096[µs]
  average fill array const char* = 526[µs]
  average fill array string_view = 568[µs]
  </code></pre>
  
  <p>Godbolt url: <a href="https://godbolt.org/z/aU7zL_" rel="nofollow noreferrer">https://godbolt.org/z/aU7zL_</a></p>
  
  <p>So in the second case <code>const char*</code> is faster as expected. And the first case was explained in the answers.</p>