# HG changeset patch # User Simon Sapin # Date 2021-03-13 07:59:03 # Node ID c94fa884240bb084f7ff23b55973b0a4c5c9b65f # Parent decc3bd3f20d5628a0dd6c49394c00e51d1abe60 rust: Preallocate the returned `Vec` in `utils::files::relativize_path` Profiling `rhg files > /dev/null` on an old snapshot of mozilla-central (with `perf` and the Firefox Profiler: https://github.com/firefox-devtools/profiler/blob/main/docs-user/guide-perf-profiling.md) showed non-trivial time spend in this function and in `realloc`. This change makes the wall-clock time for that process on my machine go from ~190 ms to ~150 ms. Differential Revision: https://phab.mercurial-scm.org/D10199 diff --git a/rust/hg-core/src/utils/files.rs b/rust/hg-core/src/utils/files.rs --- a/rust/hg-core/src/utils/files.rs +++ b/rust/hg-core/src/utils/files.rs @@ -290,7 +290,13 @@ pub fn relativize_path(path: &HgPath, cw if cwd.as_ref().is_empty() { Cow::Borrowed(path.as_bytes()) } else { - let mut res: Vec = Vec::new(); + // This is not all accurate as to how large `res` will actually be, but + // profiling `rhg files` on a large-ish repo shows it’s better than + // starting from a zero-capacity `Vec` and letting `extend` reallocate + // repeatedly. + let guesstimate = path.as_bytes().len(); + + let mut res: Vec = Vec::with_capacity(guesstimate); let mut path_iter = path.as_bytes().split(|b| *b == b'/').peekable(); let mut cwd_iter = cwd.as_ref().as_bytes().split(|b| *b == b'/').peekable();