[subset-perf] swap instead of copying vertice's when reordering during sort.
diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh
index aefa7c8..ce9ff90 100644
--- a/src/hb-repacker.hh
+++ b/src/hb-repacker.hh
@@ -49,6 +49,17 @@
     unsigned end = 0;
     unsigned priority = 0;
 
+    friend void swap (vertex_t& a, vertex_t& b)
+    {
+      hb_swap (a.obj, b.obj);
+      hb_swap (a.distance, b.distance);
+      hb_swap (a.space, b.space);
+      hb_swap (a.parents, b.parents);
+      hb_swap (a.start, b.start);
+      hb_swap (a.end, b.end);
+      hb_swap (a.priority, b.priority);
+    }
+
     bool is_shared () const
     {
       return parents.length > 1;
@@ -280,8 +291,9 @@
     {
       unsigned next_id = queue.pop_minimum().second;
 
-      vertex_t& next = vertices_[next_id];
-      sorted_graph[new_id] = next;
+      hb_swap (sorted_graph[new_id], vertices_[next_id]);
+      const vertex_t& next = sorted_graph[new_id];
+
       id_map[next_id] = new_id--;
 
       for (const auto& link : next.obj.all_links ()) {
@@ -516,12 +528,10 @@
     // The last object is the root of the graph, so swap back the root to the end.
     // The root's obj idx does change, however since it's root nothing else refers to it.
     // all other obj idx's will be unaffected.
-    vertex_t root = vertices_[vertices_.length - 2];
-    vertices_[clone_idx] = *clone;
-    vertices_[vertices_.length - 1] = root;
+    hb_swap (vertices_[vertices_.length - 2], *clone);
 
     // Since the root moved, update the parents arrays of all children on the root.
-    for (const auto& l : root.obj.all_links ())
+    for (const auto& l : root ().obj.all_links ())
       vertices_[l.objidx].remap_parent (root_idx () - 1, root_idx ());
 
     return clone_idx;
diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh
index 9ded836..5663b29 100644
--- a/src/hb-serialize.hh
+++ b/src/hb-serialize.hh
@@ -74,7 +74,7 @@
     }
 
     object_t () = default;
-    
+
 #ifdef HB_EXPERIMENTAL_API
     object_t (const hb_object_t &o)
     {
@@ -91,6 +91,15 @@
     }
 #endif
 
+    friend void swap (object_t& a, object_t& b)
+    {
+      hb_swap (a.head, b.head);
+      hb_swap (a.tail, b.tail);
+      hb_swap (a.next, b.next);
+      hb_swap (a.real_links, b.real_links);
+      hb_swap (a.virtual_links, b.virtual_links);
+    }
+
     bool operator == (const object_t &o) const
     {
       // Virtual links aren't considered for equality since they don't affect the functionality