Skip to content

Commit 9dc387c

Browse files
committed
Remove extra lookups and memory allocations from tsort graph construction
1 parent 0ccc67f commit 9dc387c

File tree

2 files changed

+16
-24
lines changed

2 files changed

+16
-24
lines changed

fuzz/Cargo.lock

Lines changed: 0 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/uu/tsort/src/tsort.rs

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ enum TsortError {
4242

4343
impl UError for TsortError {}
4444

45+
46+
4547
#[uucore::main]
4648
pub fn uumain(args: impl uucore::Args) -> UResult<()> {
4749
let matches = uucore::clap_localization::handle_clap_result(uu_app(), args)?;
@@ -63,11 +65,17 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
6365

6466
// Create the directed graph from pairs of tokens in the input data.
6567
let mut g = Graph::new(input.to_string_lossy().to_string());
66-
for ab in data.split_whitespace().collect::<Vec<&str>>().chunks(2) {
67-
match ab {
68-
[a, b] => g.add_edge(a, b),
69-
_ => return Err(TsortError::NumTokensOdd(input.to_string_lossy().to_string()).into()),
70-
}
68+
69+
let mut edgetokens = data.split_whitespace();
70+
71+
loop {
72+
let Some(a) = edgetokens.next() else {
73+
break;
74+
};
75+
let Some(b) = edgetokens.next() else {
76+
return Err(TsortError::NumTokensOdd(input.to_string_lossy().to_string()).into());
77+
};
78+
g.add_edge(a, b);
7179
}
7280

7381
g.run_tsort();
@@ -127,19 +135,11 @@ impl<'input> Graph<'input> {
127135
}
128136
}
129137

130-
fn add_node(&mut self, name: &'input str) {
131-
self.nodes.entry(name).or_default();
132-
}
133-
134138
fn add_edge(&mut self, from: &'input str, to: &'input str) {
135-
self.add_node(from);
139+
let from_node = self.nodes.entry(from).or_default();
136140
if from != to {
137-
self.add_node(to);
138-
139-
let from_node = self.nodes.get_mut(from).unwrap();
140141
from_node.add_successor(to);
141-
142-
let to_node = self.nodes.get_mut(to).unwrap();
142+
let to_node = self.nodes.entry(to).or_default();
143143
to_node.predecessor_count += 1;
144144
}
145145
}
@@ -233,10 +233,7 @@ impl<'input> Graph<'input> {
233233

234234
fn detect_cycle(&self) -> Vec<&'input str> {
235235
// Sort the nodes just to make this function deterministic.
236-
let mut nodes = Vec::new();
237-
for node in self.nodes.keys() {
238-
nodes.push(node);
239-
}
236+
let mut nodes: Vec<_> = self.nodes.keys().collect();
240237
nodes.sort_unstable();
241238

242239
let mut visited = HashSet::new();

0 commit comments

Comments
 (0)