Skip to content

Commit 8df771f

Browse files
committed
Avoid quadratic complexity when splitting output into lines
When searching for newlines in a process output keep track which part of buffer was already examined to avoid processing the same data again and again.
1 parent 9f60fca commit 8df771f

File tree

1 file changed

+14
-3
lines changed

1 file changed

+14
-3
lines changed

crates/cargo-util/src/process_builder.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -243,17 +243,27 @@ impl ProcessBuilder {
243243
.stdin(Stdio::null());
244244

245245
let mut callback_error = None;
246+
let mut stdout_pos = 0;
247+
let mut stderr_pos = 0;
246248
let status = (|| {
247249
let mut child = cmd.spawn()?;
248250
let out = child.stdout.take().unwrap();
249251
let err = child.stderr.take().unwrap();
250252
read2(out, err, &mut |is_out, data, eof| {
253+
let pos = if is_out {
254+
&mut stdout_pos
255+
} else {
256+
&mut stderr_pos
257+
};
251258
let idx = if eof {
252259
data.len()
253260
} else {
254-
match data.iter().rposition(|b| *b == b'\n') {
255-
Some(i) => i + 1,
256-
None => return,
261+
match data[*pos..].iter().rposition(|b| *b == b'\n') {
262+
Some(i) => *pos + i + 1,
263+
None => {
264+
*pos = data.len();
265+
return;
266+
}
257267
}
258268
};
259269

@@ -280,6 +290,7 @@ impl ProcessBuilder {
280290
}
281291

282292
data.drain(..idx);
293+
*pos = 0;
283294
})?;
284295
child.wait()
285296
})()

0 commit comments

Comments
 (0)