Skip to content

Commit

Permalink
Fix performance issue related to analysis sort
Browse files Browse the repository at this point in the history
The issue is that the call to `self.analysis.children.sort_by` was really slow due to having to recalculate `neighbors_directed` each time
  • Loading branch information
JonasAlaif committed Oct 26, 2024
1 parent e01cad0 commit 851ca0e
Show file tree
Hide file tree
Showing 6 changed files with 65 additions and 42 deletions.
10 changes: 4 additions & 6 deletions axiom-profiler-GUI/src/filters/add_filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,8 @@ pub fn AddFilterSidebar(props: &AddFilterSidebarProps) -> Html {
.filter(|&(n, _, _)| {
graph
.raw
.neighbors_directed(n, Direction::Outgoing)
.into_iter()
.any(|n| graph.raw[n].hidden())
.neighbors_directed_count_hidden(n, Direction::Outgoing)
> 0
})
.map(|(n, _, _)| Filter::ShowNeighbours(n, Direction::Outgoing))
.collect(),
Expand All @@ -82,9 +81,8 @@ pub fn AddFilterSidebar(props: &AddFilterSidebarProps) -> Html {
.filter(|&(n, _, _)| {
graph
.raw
.neighbors_directed(n, Direction::Incoming)
.into_iter()
.any(|n| graph.raw[n].hidden())
.neighbors_directed_count_hidden(n, Direction::Incoming)
> 0
})
.map(|(n, _, _)| Filter::ShowNeighbours(n, Direction::Incoming))
.collect(),
Expand Down
2 changes: 1 addition & 1 deletion axiom-profiler-GUI/src/results/filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Filter {
Filter::MaxInsts(n) => graph.keep_first_n_cost(n),
Filter::MaxBranching(n) => graph.keep_first_n_children(n),
Filter::ShowNeighbours(nidx, direction) => {
let nodes = graph.raw.neighbors_directed(nidx, direction);
let nodes = graph.raw.neighbors_directed_collect(nidx, direction);
graph.raw.set_visibility_many(false, nodes.into_iter())
}
Filter::VisitSubTreeWithRoot(nidx, retain) => {
Expand Down
4 changes: 2 additions & 2 deletions axiom-profiler-GUI/src/results/node_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,8 @@ pub fn SelectedNodesInfo(
<InfoLine header="To Leaf" text={format!("short {}, long {}", info.node.bwd_depth.min, info.node.bwd_depth.max)} code=false />
<InfoLine header="Degree" text={
format!("parents {}, children {}",
graph.raw.neighbors_directed(node, petgraph::Direction::Incoming).len(),
graph.raw.neighbors_directed(node, petgraph::Direction::Outgoing).len()
graph.raw.neighbors_directed_count(node, petgraph::Direction::Incoming),
graph.raw.neighbors_directed_count(node, petgraph::Direction::Outgoing),
)
} code=false />
</ul>
Expand Down
7 changes: 3 additions & 4 deletions smt-log-parser/src/analysis/graph/analysis/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,9 @@ impl InstGraph {
.reverse()
.then_with(|| a.cmp(&b))
});
self.analysis.children.sort_by(|&a, &b| {
let ac = self.raw.neighbors_directed(a, Direction::Outgoing).len();
let bc = self.raw.neighbors_directed(b, Direction::Outgoing).len();
ac.cmp(&bc).reverse().then_with(|| a.cmp(&b))
self.analysis.children.sort_by_cached_key(|&a| {
let ac = self.raw.neighbors_directed_count(a, Direction::Outgoing);
(usize::MAX - ac, a)
});
self.analysis.fwd_depth_min.sort_by(|&a, &b| {
self.raw.graph[a.0]
Expand Down
60 changes: 46 additions & 14 deletions smt-log-parser/src/analysis/graph/raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,29 +225,61 @@ impl RawInstGraph {
pub fn rev(&self) -> Reversed<&petgraph::graph::DiGraph<Node, EdgeKind, RawIx>> {
Reversed(&*self.graph)
}
/// Similar to `self.graph.neighbors_directed` but will walk through
/// disabled nodes.
pub fn neighbors_directed(
&self,
node: RawNodeIndex,
dir: Direction,
) -> FxHashSet<RawNodeIndex> {
let (mut visited, mut enabled): (FxHashSet<_>, FxHashSet<_>) = self
.graph
.neighbors_directed(node.0, dir)
.map(RawNodeIndex)
.partition(|n| self.graph[n.0].disabled());
mut f: impl FnMut(RawNodeIndex),
) {
let mut visited = FxHashSet::default();
for n in self.graph.neighbors_directed(node.0, dir) {
if self.graph[n].disabled() {
visited.insert(n);
} else {
f(RawNodeIndex(n));
}
}
let mut disabled: Vec<_> = visited.iter().copied().collect();
while let Some(next) = disabled.pop() {
for n in self.graph.neighbors_directed(next.0, dir).map(RawNodeIndex) {
if visited.insert(n) {
if self.graph[n.0].disabled() {
disabled.push(n);
} else {
enabled.insert(n);
}
for n in self.graph.neighbors_directed(next, dir) {
if !visited.insert(n) {
continue;
}
if self.graph[n].disabled() {
disabled.push(n);
} else {
f(RawNodeIndex(n));
}
}
}
enabled
}
/// Faster than [`Self::neighbors_directed_collect`] if you only need the count.
pub fn neighbors_directed_count(&self, node: RawNodeIndex, dir: Direction) -> usize {
let mut neighbors = 0;
self.neighbors_directed(node, dir, |_| neighbors += 1);
neighbors
}
pub fn neighbors_directed_count_hidden(&self, node: RawNodeIndex, dir: Direction) -> usize {
let mut hidden_neighbors = 0;
self.neighbors_directed(node, dir, |ix| {
if self[ix].hidden() {
hidden_neighbors += 1;
}
});
hidden_neighbors
}
pub fn neighbors_directed_collect(
&self,
node: RawNodeIndex,
dir: Direction,
) -> FxHashSet<RawNodeIndex> {
let mut neighbors = FxHashSet::default();
self.neighbors_directed(node, dir, |ix| {
neighbors.insert(ix);
});
neighbors
}

pub fn visible_nodes(&self) -> usize {
Expand Down
24 changes: 9 additions & 15 deletions smt-log-parser/src/analysis/graph/visible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,21 +39,15 @@ impl InstGraph {
// mapping from old node index to new node index, end represents removed.
let mut node_index_map = vec![NodeIndex::end(); self.raw.graph.node_count()];
let node_map = |idx, node: &Node| {
node.visible().then(|| VisibleNode {
idx,
hidden_parents: self
.raw
.neighbors_directed(idx, Direction::Incoming)
.into_iter()
.filter(|n| self.raw.graph[n.0].hidden())
.count() as u32,
hidden_children: self
.raw
.neighbors_directed(idx, Direction::Outgoing)
.into_iter()
.filter(|n| self.raw.graph[n.0].hidden())
.count() as u32,
max_depth: 0,
node.visible().then(|| {
let hidden_parents = self.raw.neighbors_directed_count_hidden(idx, Incoming);
let hidden_children = self.raw.neighbors_directed_count_hidden(idx, Outgoing);
VisibleNode {
idx,
hidden_parents: hidden_parents as u32,
hidden_children: hidden_children as u32,
max_depth: 0,
}
})
};
for (i, node) in self.raw.graph.node_weights().enumerate() {
Expand Down

0 comments on commit 851ca0e

Please sign in to comment.