From f08f2adc54f2713beb3103288ed9d0d7801ba99e Mon Sep 17 00:00:00 2001 From: Jake Lishman Date: Wed, 15 Apr 2026 18:50:35 +0100 Subject: [PATCH] Avoid inner-loop allocations in `longest_path` The only use of the per-node `Vec` is to consume it immediately into a `max_by` iterator. Rewriting the allocating loop as a single `try_fold` removes the unnecessary allocation. On a test 1.6 million gate circuit over on Qiskit, this sped up our use of `longest_path` from 150ms to 100ms, and there's further follow-on improvements available by changing the interfaces to allow path-length calculation without constructing the path itself. --- rustworkx-core/src/dag_algo.rs | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/rustworkx-core/src/dag_algo.rs b/rustworkx-core/src/dag_algo.rs index 734305c601..aa5a17c4d6 100644 --- a/rustworkx-core/src/dag_algo.rs +++ b/rustworkx-core/src/dag_algo.rs @@ -303,19 +303,18 @@ where // Iterate over nodes in topological order for node in nodes { - let parents = graph.edges_directed(node, petgraph::Direction::Incoming); - let mut incoming_path: Vec<(T, G::NodeId)> = Vec::new(); // Stores the distance and the previous node for each parent - for p_edge in parents { - let p_node = p_edge.source(); - let weight: T = weight_fn(p_edge)?; - let length = dist[&p_node].0 + weight; - incoming_path.push((length, p_node)); - } - // Determine the maximum distance and corresponding parent node - let max_path: (T, G::NodeId) = incoming_path - .into_iter() - .max_by(|a, b| a.0.partial_cmp(&b.0).unwrap()) - .unwrap_or((T::zero(), node)); // If there are no incoming edges, the distance is zero + let max_path = graph + .edges_directed(node, petgraph::Direction::Incoming) + .try_fold((T::zero(), node), |longest, p_edge| -> Result<_, E> { + let p_node = p_edge.source(); + let weight: T = weight_fn(p_edge)?; + let length = dist[&p_node].0 + weight; + if length >= longest.0 { + Ok((length, p_node)) + } else { + Ok(longest) + } + })?; // Store the maximum distance and the corresponding parent node for the current node dist.insert(node, max_path);