From 5b882c420adc8f0556a0d966a641aef4c812079e Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 6 Oct 2021 11:12:32 -0700 Subject: [PATCH] [repacker] performance optimizations for topological sorting. - Presize the output sorted graph and write it once in the correct order to avoid needing to reverse. - Swap the old/new graph vectors instead of copying. - Use a boolean vector for tracking visited instead of a set. --- src/hb-repacker.hh | 25 +++++++++++-------------- src/hb-vector.hh | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/hb-repacker.hh b/src/hb-repacker.hh index 1320b4220..14e105694 100644 --- a/src/hb-repacker.hh +++ b/src/hb-repacker.hh @@ -236,6 +236,7 @@ struct graph_t hb_vector_t queue; hb_vector_t sorted_graph; + if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t id_map; if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; @@ -252,7 +253,7 @@ struct graph_t queue.remove (0); vertex_t& next = vertices_[next_id]; - sorted_graph.push (next); + sorted_graph[new_id] = next; id_map[next_id] = new_id--; for (const auto& link : next.obj.links) { @@ -269,10 +270,7 @@ struct graph_t remap_all_obj_indices (id_map, &sorted_graph); - sorted_graph.as_array ().reverse (); - - vertices_.fini_deep (); - vertices_ = sorted_graph; + vertices_.swap (sorted_graph); sorted_graph.fini_deep (); } @@ -293,6 +291,7 @@ struct graph_t hb_priority_queue_t queue; hb_vector_t sorted_graph; + if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return; hb_vector_t id_map; if (unlikely (!check_success (id_map.resize (vertices_.length)))) return; @@ -308,7 +307,7 @@ struct graph_t unsigned next_id = queue.pop_minimum().second; vertex_t& next = vertices_[next_id]; - sorted_graph.push (next); + sorted_graph[new_id] = next; id_map[next_id] = new_id--; for (const auto& link : next.obj.links) { @@ -331,10 +330,7 @@ struct graph_t remap_all_obj_indices (id_map, &sorted_graph); - sorted_graph.as_array ().reverse (); - - vertices_.fini_deep (); - vertices_ = sorted_graph; + vertices_.swap (sorted_graph); sorted_graph.fini_deep (); } @@ -812,19 +808,20 @@ struct graph_t hb_priority_queue_t queue; queue.insert (0, vertices_.length - 1); - hb_set_t visited; + hb_vector_t visited; + visited.resize (vertices_.length); while (!queue.in_error () && !queue.is_empty ()) { unsigned next_idx = queue.pop_minimum ().second; - if (visited.has (next_idx)) continue; + if (visited[next_idx]) continue; const auto& next = vertices_[next_idx]; int64_t next_distance = vertices_[next_idx].distance; - visited.add (next_idx); + visited[next_idx] = true; for (const auto& link : next.obj.links) { - if (visited.has (link.objidx)) continue; + if (visited[link.objidx]) continue; const auto& child = vertices_[link.objidx].obj; int64_t child_weight = (child.tail - child.head) + diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 110d457ca..95b5295ba 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -87,6 +87,21 @@ struct hb_vector_t resize (0); } + void swap (hb_vector_t& other) + { + int allocated_copy = allocated; + unsigned int length_copy = length; + Type *arrayZ_copy = arrayZ; + + allocated = other.allocated; + length = other.length; + arrayZ = other.arrayZ; + + other.allocated = allocated_copy; + other.length = length_copy; + other.arrayZ = arrayZ_copy; + } + hb_vector_t& operator = (const hb_vector_t &o) { reset ();