Mercurial > hg
changeset 51977:42a116f1cdc1
branchmap-v3: introduce a "stop_rev" argument to `headsrevs`
The `headsrevs` method of the revlog already have a `revs` argument to compute
the headrevs of a limited set of heads. However, it disable the use of the
native compiled code to compute the heads, which slows down the branchmap v3
code a lot.
The branchmap v3 usage is actually quite constrained as we will always only
ignores a part at the top of the graph. So we could be significantly faster.
We start by making small change to the python side to improve the situation and
introduce the new API. More collaboration with the native code are coming later.
This massively speedup operation and close most of the remaining gaps between
branchmap-v3 and branchmap-v2. especially on repository with many revs like
mozilla-try. A small overhead remains mostly because the `headrevs` logic
currently has some inefficiently. We will look into them from there.
### benchmark.name = hg.command.unbundle
# bin-env-vars.hg.py-re2-module = default
# benchmark.variants.issue6528 = disabled
# benchmark.variants.resource-usage = default
# benchmark.variants.reuse-external-delta-parent = yes
# benchmark.variants.revs = any-1-extra-rev
# benchmark.variants.source = unbundle
# benchmark.variants.validate = default
# benchmark.variants.verbosity = quiet
## data-env-vars.name = netbeans-2018-08-01-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 0.233711 ~~~~~
branch-v3 before: 0.368769 (+57.79%, +0.14)
branch-v3 after: 0.239857 (+2.63%, +0.01)
# bin-env-vars.hg.flavor = rust
branch-v2: 0.235230 ~~~~~
branch-v3 before: 0.372460 (+58.34%, +0.14)
branch-v3 after: 0.240972 (+2.44%, +0.01)
## data-env-vars.name = netbeans-2018-08-01-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 0.255586 ~~~~~
branch-v3 before: 0.318907 (+24.78%, +0.06)
branch-v3 after: 0.268560 (+5.08%, +0.01)
## data-env-vars.name = mozilla-central-2024-03-22-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 0.339010 ~~~~~
branch-v3 before: 0.349752 (+3.17%, +0.01)
branch-v3 after: 0.349389 (+3.06%, +0.01)
# bin-env-vars.hg.flavor = rust
branch-v2: 0.346525 ~~~~~
branch-v3 before: 0.354300 (+2.24%, +0.01)
branch-v3 after: 0.355661 (+2.64%, +0.01)
## data-env-vars.name = mozilla-central-2024-03-22-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 0.380202 ~~~~~
branch-v3 before: 0.396293 (+4.23%, +0.02)
branch-v3 after: 0.408851 (+7.54%, +0.03)
## data-env-vars.name = mozilla-unified-2024-03-22-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 0.412165 ~~~~~
branch-v3 before: 0.424769 (+3.06%, +0.01)
branch-v3 after: 0.427782 (+3.79%, +0.02)
# bin-env-vars.hg.flavor = rust
branch-v2: 0.412397 ~~~~~
branch-v3 before: 0.421796 (+2.28%, +0.01)
branch-v3 after: 0.422354 (+2.41%, +0.01)
## data-env-vars.name = mozilla-unified-2024-03-22-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 0.429501 ~~~~~
branch-v3 before: 0.443849 (+3.34%, +0.01)
branch-v3 after: 0.443197 (+3.19%, +0.01)
## data-env-vars.name = mozilla-try-2024-03-26-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 3.403171 ~~~~~
branch-v3 before: 6.234055 (+83.18%, +2.83)
branch-v3 after: 3.819477 (+12.23%, +0.42)
# bin-env-vars.hg.flavor = rust
branch-v2: 3.454876 ~~~~~
branch-v3 before: 6.307813 (+82.58%, +2.85)
branch-v3 after: 3.590284 (+3.92%, +0.14)
## data-env-vars.name = mozilla-try-2024-03-26-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 3.465435 ~~~~~
branch-v3 before: 5.176076 (+49.36%, +1.71)
branch-v3 after: 3.633278 (+4.84%, +0.17)
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Tue, 03 Sep 2024 11:11:17 +0200 |
parents | 41b8892a2054 |
children | 5d1e6f447d2d |
files | mercurial/branchmap.py mercurial/repoview.py mercurial/revlog.py |
diffstat | 3 files changed, 16 insertions(+), 6 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/branchmap.py Tue Sep 03 02:13:03 2024 +0200 +++ b/mercurial/branchmap.py Tue Sep 03 11:11:17 2024 +0200 @@ -884,8 +884,7 @@ elif self.tiprev == cl.tiprev(): return cl.headrevs() else: - # XXX passing tiprev as ceiling of cl.headrevs could be faster - heads = cl.headrevs(cl.revs(stop=self.tiprev)) + heads = cl.headrevs(stop_rev=self.tiprev + 1) return heads def _write_header(self, fp) -> None:
--- a/mercurial/repoview.py Tue Sep 03 02:13:03 2024 +0200 +++ b/mercurial/repoview.py Tue Sep 03 11:11:17 2024 +0200 @@ -310,9 +310,14 @@ # no Rust fast path implemented yet, so just loop in Python return [self.node(r) for r in self.headrevs()] - def headrevs(self, revs=None): + def headrevs(self, revs=None, stop_rev=None): if revs is None: - return self.index.headrevs(self.filteredrevs) + filtered = self.filteredrevs + if stop_rev is not None and stop_rev < len(self.index): + filtered = set(self.filteredrevs) + filtered.update(range(stop_rev, len(self.index))) + return self.index.headrevs(filtered) + assert stop_rev is None revs = self._checknofilteredinrevs(revs) return super(filteredchangelogmixin, self).headrevs(revs)
--- a/mercurial/revlog.py Tue Sep 03 02:13:03 2024 +0200 +++ b/mercurial/revlog.py Tue Sep 03 11:11:17 2024 +0200 @@ -2380,9 +2380,15 @@ assert heads return (orderedout, roots, heads) - def headrevs(self, revs=None): + def headrevs(self, revs=None, stop_rev=None): if revs is None: - return self.index.headrevs() + excluded = None + if stop_rev is not None and stop_rev < len(self.index): + # We should let the native code handle it, but that a + # simple enough first step. + excluded = range(stop_rev, len(self.index)) + return self.index.headrevs(excluded) + assert stop_rev is None if rustdagop is not None and self.index.rust_ext_compat: return rustdagop.headrevs(self.index, revs) return dagop.headrevs(revs, self._uncheckedparentrevs)