# HG changeset patch # User Pierre-Yves David # Date 1686020214 -7200 # Node ID 459681233b1f9a450eeb19f952c9d9bea19f16a8 # Parent b8de54ac5a21f317b305578e4a1e0dbabc82e658 perf: add a perf::stream-consume We know how long it take to generate, lets check how long it take to apply now. diff -r b8de54ac5a21 -r 459681233b1f contrib/perf.py --- a/contrib/perf.py Tue Jun 06 04:09:05 2023 +0200 +++ b/contrib/perf.py Tue Jun 06 04:56:54 2023 +0200 @@ -2024,6 +2024,85 @@ fm.end() +@command( + b'perf::stream-consume', + formatteropts, +) +def perf_stream_clone_consume(ui, repo, filename, **opts): + """benchmark the full application of a stream clone + + This include the creation of the repository + """ + # try except to appease check code + msg = b"mercurial too old, missing necessary module: %s" + try: + from mercurial import bundle2 + except ImportError as exc: + msg %= _bytestr(exc) + raise error.Abort(msg) + try: + from mercurial import exchange + except ImportError as exc: + msg %= _bytestr(exc) + raise error.Abort(msg) + try: + from mercurial import hg + except ImportError as exc: + msg %= _bytestr(exc) + raise error.Abort(msg) + try: + from mercurial import localrepo + except ImportError as exc: + msg %= _bytestr(exc) + raise error.Abort(msg) + + opts = _byteskwargs(opts) + timer, fm = gettimer(ui, opts) + + # deletion of the generator may trigger some cleanup that we do not want to + # measure + if not (os.path.isfile(filename) and os.access(filename, os.R_OK)): + raise error.Abort("not a readable file: %s" % filename) + + run_variables = [None, None] + + @contextlib.contextmanager + def context(): + with open(filename, mode='rb') as bundle: + with tempfile.TemporaryDirectory() as tmp_dir: + tmp_dir = fsencode(tmp_dir) + run_variables[0] = bundle + run_variables[1] = tmp_dir + yield + run_variables[0] = None + run_variables[1] = None + + def runone(): + bundle = run_variables[0] + tmp_dir = run_variables[1] + # only pass ui when no srcrepo + localrepo.createrepository( + repo.ui, tmp_dir, requirements=repo.requirements + ) + target = hg.repository(repo.ui, tmp_dir) + gen = exchange.readbundle(target.ui, bundle, bundle.name) + # stream v1 + if util.safehasattr(gen, 'apply'): + gen.apply(target) + else: + with target.transaction(b"perf::stream-consume") as tr: + bundle2.applybundle( + target, + gen, + tr, + source=b'unbundle', + url=filename, + ) + + timer(runone, context=context, title=b"consume") + fm.end() + + @command(b'perf::parents|perfparents', formatteropts) def perfparents(ui, repo, **opts): """benchmark the time necessary to fetch one changeset's parents. diff -r b8de54ac5a21 -r 459681233b1f tests/test-contrib-perf.t --- a/tests/test-contrib-perf.t Tue Jun 06 04:09:05 2023 +0200 +++ b/tests/test-contrib-perf.t Tue Jun 06 04:56:54 2023 +0200 @@ -188,6 +188,8 @@ perf::startup (no help text available) perf::status benchmark the performance of a single status call + perf::stream-consume + benchmark the full application of a stream clone perf::stream-generate benchmark the full generation of a stream clone perf::stream-locked-section