comparison rust/hg-core/src/utils/files.rs @ 46775:c94fa884240b

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
author Simon Sapin <simon.sapin@octobus.net>
date Sat, 13 Mar 2021 08:59:03 +0100
parents 3c9ddb1986a9
children be579775c2d9
comparison
equal deleted inserted replaced
46774:decc3bd3f20d 46775:c94fa884240b
288 /// ``` 288 /// ```
289 pub fn relativize_path(path: &HgPath, cwd: impl AsRef<HgPath>) -> Cow<[u8]> { 289 pub fn relativize_path(path: &HgPath, cwd: impl AsRef<HgPath>) -> Cow<[u8]> {
290 if cwd.as_ref().is_empty() { 290 if cwd.as_ref().is_empty() {
291 Cow::Borrowed(path.as_bytes()) 291 Cow::Borrowed(path.as_bytes())
292 } else { 292 } else {
293 let mut res: Vec<u8> = Vec::new(); 293 // This is not all accurate as to how large `res` will actually be, but
294 // profiling `rhg files` on a large-ish repo shows it’s better than
295 // starting from a zero-capacity `Vec` and letting `extend` reallocate
296 // repeatedly.
297 let guesstimate = path.as_bytes().len();
298
299 let mut res: Vec<u8> = Vec::with_capacity(guesstimate);
294 let mut path_iter = path.as_bytes().split(|b| *b == b'/').peekable(); 300 let mut path_iter = path.as_bytes().split(|b| *b == b'/').peekable();
295 let mut cwd_iter = 301 let mut cwd_iter =
296 cwd.as_ref().as_bytes().split(|b| *b == b'/').peekable(); 302 cwd.as_ref().as_bytes().split(|b| *b == b'/').peekable();
297 loop { 303 loop {
298 match (path_iter.peek(), cwd_iter.peek()) { 304 match (path_iter.peek(), cwd_iter.peek()) {