diff --git a/src/common/gmsh.cpp b/src/common/gmsh.cpp
index e73fcdeb3d40a79d52bbf212544cdb245243c2ad..8dd5c0f7c78e98ed35c048f9f89aea1da9f3603a 100644
--- a/src/common/gmsh.cpp
+++ b/src/common/gmsh.cpp
@@ -362,6 +362,7 @@ GMSH_API void gmsh::model::getEntities(vectorpair &dimTags, const int dim)
   dimTags.clear();
   std::vector<GEntity *> entities;
   GModel::current()->getEntities(entities, dim);
+  dimTags.reserve(entities.size());
   for(auto ge : entities)
     dimTags.push_back(std::make_pair(ge->dim(), ge->tag()));
 }
@@ -3553,7 +3554,7 @@ GMSH_API void gmsh::model::mesh::createEdges(const vectorpair &dimTags)
       MElement *e = ge->getMeshElement(j);
       for(int k = 0; k < e->getNumEdges(); k++) {
         MEdge edge = e->getEdge(k);
-        GModel::current()->addMEdge(edge);
+        GModel::current()->addMEdge(std::move(edge));
       }
     }
   }
@@ -3570,7 +3571,7 @@ GMSH_API void gmsh::model::mesh::createFaces(const vectorpair &dimTags)
       MElement *e = ge->getMeshElement(j);
       for(int k = 0; k < e->getNumFaces(); k++) {
         MFace face = e->getFace(k);
-        GModel::current()->addMFace(face);
+        GModel::current()->addMFace(std::move(face));
       }
     }
   }
@@ -3580,9 +3581,9 @@ GMSH_API void gmsh::model::mesh::getAllEdges(std::vector<std::size_t> &edgeTags,
                                              std::vector<std::size_t> &edgeNodes)
 {
   if(!_checkInit()) return;
-  edgeTags.clear();
-  edgeNodes.clear();
   GModel *m = GModel::current();
+  edgeTags .clear(); edgeTags .reserve(m->getNumEdges());
+  edgeNodes.clear(); edgeNodes.reserve(m->getNumEdges() * 2);
   for(auto it = m->firstMEdge(); it != m->lastMEdge(); ++it) {
     edgeTags.push_back(it->second);
     edgeNodes.push_back(it->first.getVertex(0)->getNum());
@@ -3630,7 +3631,7 @@ GMSH_API void gmsh::model::mesh::addEdges(const std::vector<std::size_t> &edgeTa
       }
     }
     MEdge e(v[0], v[1]);
-    m->addMEdge(e, edgeTags[i]);
+    m->addMEdge(std::move(e), edgeTags[i]);
   }
 }
 
@@ -3658,7 +3659,7 @@ GMSH_API void gmsh::model::mesh::addFaces(const int faceType,
       }
     }
     MFace f(v[0], v[1], v[2], v[3]);
-    m->addMFace(f, faceTags[i]);
+    m->addMFace(std::move(f), faceTags[i]);
   }
 }
 
@@ -3854,7 +3855,7 @@ GMSH_API void gmsh::model::mesh::getKeys(
             coordEdge[1] = 0.5 * (v1->y() + v2->y());
             coordEdge[2] = 0.5 * (v1->z() + v2->z());
           }
-          std::size_t edgeGlobalIndice = GModel::current()->addMEdge(edge);
+          std::size_t edgeGlobalIndice = GModel::current()->addMEdge(std::move(edge));
           for(int k = 1; k < const1; k++) {
             typeKeys.push_back(k);
             entityKeys.push_back(edgeGlobalIndice);
@@ -3883,7 +3884,7 @@ GMSH_API void gmsh::model::mesh::getKeys(
             coordFace[1] /= face.getNumVertices();
             coordFace[2] /= face.getNumVertices();
           }
-          std::size_t faceGlobalIndice = GModel::current()->addMFace(face);
+          std::size_t faceGlobalIndice = GModel::current()->addMFace(std::move(face));
           int it2 = const2;
           if(jj >= numberQuadFaces) { it2 = const3; }
           for(int k = const1; k < it2; k++) {
@@ -4080,7 +4081,7 @@ GMSH_API void gmsh::model::mesh::getKeysForElement(
         coordEdge[1] = 0.5 * (v1->y() + v2->y());
         coordEdge[2] = 0.5 * (v1->z() + v2->z());
       }
-      std::size_t edgeGlobalIndice = GModel::current()->addMEdge(edge);
+      std::size_t edgeGlobalIndice = GModel::current()->addMEdge(std::move(edge));
       for(int k = 1; k < const1; k++) {
         typeKeys.push_back(k);
         entityKeys.push_back(edgeGlobalIndice);
@@ -4108,7 +4109,7 @@ GMSH_API void gmsh::model::mesh::getKeysForElement(
         coordFace[1] /= face.getNumVertices();
         coordFace[2] /= face.getNumVertices();
       }
-      std::size_t faceGlobalIndice = GModel::current()->addMFace(face);
+      std::size_t faceGlobalIndice = GModel::current()->addMFace(std::move(face));
       int it2 = const2;
       if(jj >= numberQuadFaces) { it2 = const3; }
       for(int k = const1; k < it2; k++) {
diff --git a/src/geo/GModel.cpp b/src/geo/GModel.cpp
index c8e174e55db6e7fa69e5e07dac15d5560b7df048..6169dbc6814f5ba5609240e4617aec32978729d2 100644
--- a/src/geo/GModel.cpp
+++ b/src/geo/GModel.cpp
@@ -1636,7 +1636,7 @@ std::size_t GModel::getNumMeshParentElements() const
   return n;
 }
 
-std::size_t GModel::addMEdge(MEdge &edge, std::size_t num)
+std::size_t GModel::addMEdge(MEdge &&edge, std::size_t num)
 {
   std::pair<MEdge, std::size_t> key(std::move(edge),
                                     num ? num : _mapEdgeNum.size() + 1);
@@ -1658,7 +1658,7 @@ std::size_t GModel::getMEdge(MVertex *v0, MVertex *v1, MEdge &edge)
   }
 }
 
-std::size_t GModel::addMFace(MFace &face, std::size_t num)
+std::size_t GModel::addMFace(MFace &&face, std::size_t num)
 {
   std::pair<MFace, std::size_t> key(std::move(face),
                                     num ? num : _mapFaceNum.size() + 1);
diff --git a/src/geo/GModel.h b/src/geo/GModel.h
index b5b37fb3cb5a6e11a05fa16ebdf528600f2b42c7..dc4125886269e956c4e03f58a7aa3ada7e7a1a9a 100644
--- a/src/geo/GModel.h
+++ b/src/geo/GModel.h
@@ -274,8 +274,13 @@ public:
 
   // add a mesh edge or face in the global edge or face map with number "num",
   // or number it (starting at 1) if num == 0
-  std::size_t addMEdge(MEdge &edge, std::size_t num = 0);
-  std::size_t addMFace(MFace &face, std::size_t num = 0);
+  std::size_t addMEdge(MEdge &&edge, std::size_t num = 0);
+  std::size_t addMFace(MFace &&face, std::size_t num = 0);
+
+  // get number of edges or faces
+  std::size_t getNumEdges() const { return _mapEdgeNum.size(); };
+  std::size_t getNumFaces() const { return _mapFaceNum.size(); };
+
   // get the edge of face and its global number given mesh nodes (return 0 if
   // the edge or face does not exist in the edge or face map)
   std::size_t getMEdge(MVertex *v0, MVertex *v1, MEdge &edge);