changeset 40802:f723014677a5

perf: add a `perfbranchmapupdate` command This command benchmark the time necessary to update the branchmap between two sets of revisions. This changeset introduce a first version, doing nothing fancy regarding cache or other internal details.
author Boris Feld <boris.feld@octobus.net>
date Wed, 21 Nov 2018 12:02:25 +0000
parents 33d30fb1e4ae
children 95f35c873463
files contrib/perf.py tests/test-contrib-perf.t
diffstat 2 files changed, 60 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/contrib/perf.py	Mon Nov 05 13:52:19 2018 +0800
+++ b/contrib/perf.py	Wed Nov 21 12:02:25 2018 +0000
@@ -2282,6 +2282,61 @@
         branchcachewrite.restore()
     fm.end()
 
+@command(b'perfbranchmapupdate', [
+     (b'', b'base', [], b'subset of revision to start from'),
+     (b'', b'target', [], b'subset of revision to end with'),
+    ] + formatteropts)
+def perfbranchmapupdate(ui, repo, base=(), target=(), **opts):
+    """benchmark branchmap update from for <base> revs to <target> revs
+
+    Examples:
+
+       # update for the one last revision
+       $ hg perfbranchmapupdate --base 'not tip' --target 'tip'
+
+       $ update for change coming with a new branch
+       $ hg perfbranchmapupdate --base 'stable' --target 'default'
+    """
+    from mercurial import branchmap
+    opts = _byteskwargs(opts)
+    timer, fm = gettimer(ui, opts)
+    x = [None] # used to pass data between closure
+
+    # we use a `list` here to avoid possible side effect from smartset
+    baserevs = list(scmutil.revrange(repo, base))
+    targetrevs = list(scmutil.revrange(repo, target))
+    if not baserevs:
+        raise error.Abort(b'no revisions selected for --base')
+    if not targetrevs:
+        raise error.Abort(b'no revisions selected for --target')
+
+    # make sure the target branchmap also contains the one in the base
+    targetrevs = list(set(baserevs) | set(targetrevs))
+    targetrevs.sort()
+
+    cl = repo.changelog
+    allbaserevs = list(cl.ancestors(baserevs, inclusive=True))
+    allbaserevs.sort()
+    alltargetrevs = frozenset(cl.ancestors(targetrevs, inclusive=True))
+
+    newrevs = list(alltargetrevs.difference(allbaserevs))
+    newrevs.sort()
+
+    msg = b'benchmark of branchmap with %d revisions with %d new ones\n'
+    ui.status(msg % (len(allbaserevs), len(newrevs)))
+
+    base = branchmap.branchcache()
+    base.update(repo, allbaserevs)
+
+    def setup():
+        x[0] = base.copy()
+
+    def bench():
+        x[0].update(repo, newrevs)
+
+    timer(bench, setup=setup)
+    fm.end()
+
 @command(b'perfbranchmapload', [
      (b'f', b'filter', b'', b'Specify repoview filter'),
      (b'', b'list', False, b'List brachmap filter caches'),
--- a/tests/test-contrib-perf.t	Mon Nov 05 13:52:19 2018 +0800
+++ b/tests/test-contrib-perf.t	Wed Nov 21 12:02:25 2018 +0000
@@ -57,6 +57,9 @@
                  benchmark the update of a branchmap
    perfbranchmapload
                  benchmark reading the branchmap
+   perfbranchmapupdate
+                 benchmark branchmap update from for <base> revs to <target>
+                 revs
    perfbundleread
                  Benchmark reading of bundle files.
    perfcca       (no help text available)
@@ -145,6 +148,8 @@
   $ hg perfbookmarks
   $ hg perfbranchmap
   $ hg perfbranchmapload
+  $ hg perfbranchmapupdate --base "not tip" --target "tip"
+  benchmark of branchmap with 3 revisions with 1 new ones
   $ hg perfcca
   $ hg perfchangegroupchangelog
   $ hg perfchangegroupchangelog --cgversion 01