Patchwork D10199: rust: Preallocate the returned `Vec` in `utils::files::relativize_path`

login
register
mail settings
Submitter phabricator
Date March 13, 2021, 8:02 a.m.
Message ID <differential-rev-PHID-DREV-on2j6unwsmep5uljjnma-req@mercurial-scm.org>
Download mbox | patch
Permalink /patch/48514/
State Superseded
Headers show

Comments

phabricator - March 13, 2021, 8:02 a.m.
SimonSapin created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.

REVISION SUMMARY
  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 in my machine
  go from ~220 ms to ~170 ms.

REPOSITORY
  rHG Mercurial

BRANCH
  default

REVISION DETAIL
  https://phab.mercurial-scm.org/D10199

AFFECTED FILES
  rust/hg-core/src/utils/files.rs

CHANGE DETAILS




To: SimonSapin, #hg-reviewers
Cc: mercurial-patches, mercurial-devel

Patch

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
@@ -281,7 +281,13 @@ 
     if cwd.as_ref().is_empty() {
         Cow::Borrowed(path.as_bytes())
     } else {
-        let mut res: Vec<u8> = 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<u8> = 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();