[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.
This commit is contained in:
Garret Rieger 2021-10-06 11:12:32 -07:00
parent ff7a86e9b0
commit 5b882c420a
2 changed files with 26 additions and 14 deletions

View File

@ -236,6 +236,7 @@ struct graph_t
hb_vector_t<unsigned> queue;
hb_vector_t<vertex_t> sorted_graph;
if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
hb_vector_t<unsigned> 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<vertex_t> sorted_graph;
if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
hb_vector_t<unsigned> 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<bool> 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) +

View File

@ -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 ();