diff --git a/demos/api/import_perf.cpp b/demos/api/import_perf.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d17205e5970996dba1a3d3f2749ce0e245dc9058
--- /dev/null
+++ b/demos/api/import_perf.cpp
@@ -0,0 +1,69 @@
+#include <gmsh.h>
+#include <math.h>
+
+int main()
+{
+  gmsh::initialize();
+
+  int N = 2500;
+
+  double tic = gmsh::logger::getWallTime();
+  std::vector<double> coords; // x, y, z coordinates of all the nodes
+  std::vector<std::size_t> nodes; // tags of corresponding nodes
+  std::vector<std::size_t> tris; // connectivities (node tags) of triangle elements
+
+  auto tag = [N](int i, int j) {
+    return (N + 1) * i + j + 1;
+  };
+
+  for(int i = 0; i < N + 1; i++) {
+    for(int j = 0; j < N + 1; j++) {
+      nodes.push_back(tag(i, j));
+      coords.push_back((double)i / N);
+      coords.push_back((double)j / N);
+      coords.push_back(0.05 * sin(10 * (double)(i + j) / N));
+      if(i > 0 && j > 0) {
+        tris.push_back(tag(i - 1, j - 1));
+        tris.push_back(tag(i, j - 1));
+        tris.push_back(tag(i - 1, j));
+        tris.push_back(tag(i, j - 1));
+        tris.push_back(tag(i, j));
+        tris.push_back(tag(i - 1, j));
+      }
+    }
+  }
+
+  double toc = gmsh::logger::getWallTime();
+  printf("==> created nodes and connectivities in %g seconds\n", toc - tic);
+
+  tic = gmsh::logger::getWallTime();
+  int surf = gmsh::model::addDiscreteEntity(2);
+  toc = gmsh::logger::getWallTime();
+  printf("==> created surface in %g seconds\n", toc - tic);
+
+  tic = gmsh::logger::getWallTime();
+  gmsh::model::mesh::addNodes(2, 1, nodes, coords);
+  toc = gmsh::logger::getWallTime();
+  printf("==> imported nodes in %g seconds\n", toc - tic);
+
+  tic = gmsh::logger::getWallTime();
+  gmsh::model::mesh::addElementsByType(1, 2, {}, tris);
+  toc = gmsh::logger::getWallTime();
+  printf("==> imported elements in %g seconds\n", toc - tic);
+
+  tic = gmsh::logger::getWallTime();
+  gmsh::option::setNumber("Mesh.Binary", 1);
+  gmsh::write("import_perf.msh");
+  toc = gmsh::logger::getWallTime();
+  printf("==> wrote to disk in %g seconds\n", toc - tic);
+
+  tic = gmsh::logger::getWallTime();
+  gmsh::merge("import_perf.msh");
+  toc = gmsh::logger::getWallTime();
+  printf("==> read from disk in %g seconds\n", toc - tic);
+
+  //gmsh::fltk::run();
+
+  gmsh::finalize();
+  return 0;
+}
diff --git a/demos/api/import_perf.py b/demos/api/import_perf.py
new file mode 100644
index 0000000000000000000000000000000000000000..9a0f0d7df0f302a72583983950de901a2bbd7774
--- /dev/null
+++ b/demos/api/import_perf.py
@@ -0,0 +1,57 @@
+import gmsh
+import math
+
+gmsh.initialize()
+
+N = 2500
+
+tic = gmsh.logger.getWallTime()
+coords = []  # x, y, z coordinates of all the nodes
+nodes = []  # tags of corresponding nodes
+tris = []  # connectivities (node tags) of triangle elements
+
+def tag(i, j):
+    return (N + 1) * i + j + 1
+
+for i in range(N + 1):
+    for j in range(N + 1):
+        nodes.append(tag(i, j))
+        coords.extend([
+            float(i) / N,
+            float(j) / N, 0.05 * math.sin(10 * float(i + j) / N)
+        ])
+        if i > 0 and j > 0:
+            tris.extend([tag(i - 1, j - 1), tag(i, j - 1), tag(i - 1, j)])
+            tris.extend([tag(i, j - 1), tag(i, j), tag(i - 1, j)])
+toc = gmsh.logger.getWallTime()
+print("==> created nodes and connectivities in {} seconds".format(toc - tic))
+
+tic = gmsh.logger.getWallTime()
+surf = gmsh.model.addDiscreteEntity(2)
+toc = gmsh.logger.getWallTime()
+print("==> created surface in {} seconds".format(toc - tic))
+
+tic = gmsh.logger.getWallTime()
+gmsh.model.mesh.addNodes(2, 1, nodes, coords)
+toc = gmsh.logger.getWallTime()
+print("==> imported nodes in {} seconds".format(toc - tic))
+
+tic = gmsh.logger.getWallTime()
+gmsh.model.mesh.addElementsByType(1, 2, [], tris)
+toc = gmsh.logger.getWallTime()
+print("==> imported elements in {} seconds".format(toc - tic))
+
+tic = gmsh.logger.getWallTime()
+gmsh.option.setNumber("Mesh.Binary", 1)
+gmsh.write("import_perf.msh")
+toc = gmsh.logger.getWallTime()
+print("==> wrote to disk in {} seconds".format(toc - tic))
+
+tic = gmsh.logger.getWallTime()
+gmsh.merge("import_perf.msh")
+toc = gmsh.logger.getWallTime()
+print("==> read from disk in {} seconds".format(toc - tic))
+
+#gmsh.fltk.run()
+
+gmsh.finalize()