[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:
parent
ff7a86e9b0
commit
5b882c420a
|
@ -236,6 +236,7 @@ struct graph_t
|
||||||
|
|
||||||
hb_vector_t<unsigned> queue;
|
hb_vector_t<unsigned> queue;
|
||||||
hb_vector_t<vertex_t> sorted_graph;
|
hb_vector_t<vertex_t> sorted_graph;
|
||||||
|
if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
|
||||||
hb_vector_t<unsigned> id_map;
|
hb_vector_t<unsigned> id_map;
|
||||||
if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
|
if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
|
||||||
|
|
||||||
|
@ -252,7 +253,7 @@ struct graph_t
|
||||||
queue.remove (0);
|
queue.remove (0);
|
||||||
|
|
||||||
vertex_t& next = vertices_[next_id];
|
vertex_t& next = vertices_[next_id];
|
||||||
sorted_graph.push (next);
|
sorted_graph[new_id] = next;
|
||||||
id_map[next_id] = new_id--;
|
id_map[next_id] = new_id--;
|
||||||
|
|
||||||
for (const auto& link : next.obj.links) {
|
for (const auto& link : next.obj.links) {
|
||||||
|
@ -269,10 +270,7 @@ struct graph_t
|
||||||
|
|
||||||
remap_all_obj_indices (id_map, &sorted_graph);
|
remap_all_obj_indices (id_map, &sorted_graph);
|
||||||
|
|
||||||
sorted_graph.as_array ().reverse ();
|
vertices_.swap (sorted_graph);
|
||||||
|
|
||||||
vertices_.fini_deep ();
|
|
||||||
vertices_ = sorted_graph;
|
|
||||||
sorted_graph.fini_deep ();
|
sorted_graph.fini_deep ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,6 +291,7 @@ struct graph_t
|
||||||
|
|
||||||
hb_priority_queue_t queue;
|
hb_priority_queue_t queue;
|
||||||
hb_vector_t<vertex_t> sorted_graph;
|
hb_vector_t<vertex_t> sorted_graph;
|
||||||
|
if (unlikely (!check_success (sorted_graph.resize (vertices_.length)))) return;
|
||||||
hb_vector_t<unsigned> id_map;
|
hb_vector_t<unsigned> id_map;
|
||||||
if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
|
if (unlikely (!check_success (id_map.resize (vertices_.length)))) return;
|
||||||
|
|
||||||
|
@ -308,7 +307,7 @@ struct graph_t
|
||||||
unsigned next_id = queue.pop_minimum().second;
|
unsigned next_id = queue.pop_minimum().second;
|
||||||
|
|
||||||
vertex_t& next = vertices_[next_id];
|
vertex_t& next = vertices_[next_id];
|
||||||
sorted_graph.push (next);
|
sorted_graph[new_id] = next;
|
||||||
id_map[next_id] = new_id--;
|
id_map[next_id] = new_id--;
|
||||||
|
|
||||||
for (const auto& link : next.obj.links) {
|
for (const auto& link : next.obj.links) {
|
||||||
|
@ -331,10 +330,7 @@ struct graph_t
|
||||||
|
|
||||||
remap_all_obj_indices (id_map, &sorted_graph);
|
remap_all_obj_indices (id_map, &sorted_graph);
|
||||||
|
|
||||||
sorted_graph.as_array ().reverse ();
|
vertices_.swap (sorted_graph);
|
||||||
|
|
||||||
vertices_.fini_deep ();
|
|
||||||
vertices_ = sorted_graph;
|
|
||||||
sorted_graph.fini_deep ();
|
sorted_graph.fini_deep ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,19 +808,20 @@ struct graph_t
|
||||||
hb_priority_queue_t queue;
|
hb_priority_queue_t queue;
|
||||||
queue.insert (0, vertices_.length - 1);
|
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 ())
|
while (!queue.in_error () && !queue.is_empty ())
|
||||||
{
|
{
|
||||||
unsigned next_idx = queue.pop_minimum ().second;
|
unsigned next_idx = queue.pop_minimum ().second;
|
||||||
if (visited.has (next_idx)) continue;
|
if (visited[next_idx]) continue;
|
||||||
const auto& next = vertices_[next_idx];
|
const auto& next = vertices_[next_idx];
|
||||||
int64_t next_distance = vertices_[next_idx].distance;
|
int64_t next_distance = vertices_[next_idx].distance;
|
||||||
visited.add (next_idx);
|
visited[next_idx] = true;
|
||||||
|
|
||||||
for (const auto& link : next.obj.links)
|
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;
|
const auto& child = vertices_[link.objidx].obj;
|
||||||
int64_t child_weight = (child.tail - child.head) +
|
int64_t child_weight = (child.tail - child.head) +
|
||||||
|
|
|
@ -87,6 +87,21 @@ struct hb_vector_t
|
||||||
resize (0);
|
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)
|
hb_vector_t& operator = (const hb_vector_t &o)
|
||||||
{
|
{
|
||||||
reset ();
|
reset ();
|
||||||
|
|
Loading…
Reference in New Issue