title: std::vector reserve being more costly than expected
body: <p>So I need to manually handle the memory allocated by an std::vector for efficiency purposes. And I noticed that my program was slower than expected, so I added this idiom everywhere in my code base:</p>
  <pre><code>const uint new_edges_capacity = mesh.edges.size() + 6;
  if(new_edges_capacity &gt; mesh.edges.capacity())
      mesh.edges.reserve(new_edges_capacity * 2);
  </code></pre>
  <p>Originally I was simply doing:</p>
  <pre><code>const uint new_edges_capacity = mesh.edges.size() + 6; 
  mesh.edges.reserve(new_edges_capacity * 2);
  </code></pre>
  <p>Well, that first snippet is orders of magnitude faster than the second.
  I don't understand, the official documentation seems to suggest that reserve should already be doing the same check I am. However, <code>perf</code> definitely marks std::reserve as the most expensive operation in my code, and indeed the modification shows that not calling reserve and relying on it to check for allocation is faster.</p>
  <p>An example of a function where I am using this pattern:</p>
  <pre><code>template&lt;typename V&gt;
  void HMesh&lt;V&gt;::SplitFace(uint face_id, HMesh&lt;V&gt;&amp; mesh)
  {
      mesh.vertex_data.push_back({});
      mesh.verts.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MVert&amp; c = mesh.verts.back();
  
      const uint new_edges_capacity = mesh.edges.size() + 6;
      if(new_edges_capacity &gt; mesh.edges.capacity())
          mesh.edges.reserve(new_edges_capacity * 2);
      mesh.edges.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MEdge&amp; n00 = mesh.edges.back();
      mesh.edges.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MEdge&amp; n01 = mesh.edges.back();
      mesh.edges.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MEdge&amp; n10 = mesh.edges.back();
      mesh.edges.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MEdge&amp; n11 = mesh.edges.back();
      mesh.edges.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MEdge&amp; n20 = mesh.edges.back();
      mesh.edges.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MEdge&amp; n21 = mesh.edges.back();
  
      const uint new_faces_capacity = mesh.faces.size() + 2;
      if(new_faces_capacity &gt; mesh.faces.capacity())
          mesh.faces.reserve(new_faces_capacity * 2);
      mesh.faces.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MFace&amp; f1 = mesh.faces.back();
      mesh.faces.push_back({&amp;mesh});
      HMesh&lt;V&gt;::MFace&amp; f2 = mesh.faces.back();
  
      auto&amp; face = mesh.faces[face_id];
  
      HMesh&lt;V&gt;::MFace&amp; f0 = face;
  
      HMesh&lt;V&gt;::MEdge&amp; e0 = face.EdgeD();
      HMesh&lt;V&gt;::MEdge&amp; e1 = face.EdgeD().NextD();
      HMesh&lt;V&gt;::MEdge&amp; e2 = face.EdgeD().PrevD();
  
      HMesh&lt;V&gt;::MVert&amp; v0 = e0.VertD();
      HMesh&lt;V&gt;::MVert&amp; v1 = e1.VertD();
      HMesh&lt;V&gt;::MVert&amp; v2 = e2.VertD();
  
      ConnectFace(f0, n00, e0, n10);
      ConnectFace(f1, n11, e1, n21);
      ConnectFace(f2, n20, e2, n01);
  
      Pair(n00, n01);
      Pair(n10, n11);
      Pair(n20, n21);
  
      AttachVertices(n00, c, v0);
      AttachVertices(n11, c, v1);
      AttachVertices(n20, c, v2);
  
      c.Data({
          (v0.Data().position + v1.Data().position + v2.Data().position) / 3.0,
          (v0.Data().uv + v1.Data().uv + v2.Data().uv) / 3.0,
          {0,0,1}
      });
  }
  </code></pre>