Mercurial > hg
view contrib/perf-utils/compare-discovery-case @ 49463:5acbc550d987
compare-disco: support for `file` nodes specification
This leverage the `nodefromfile` feature in core. This make it possible for
callers to no longer pay the subset computation cost (and to make sure the
subset is the right one, even when the base repository is different)
author | Pierre-Yves DAVID <pierre-yves.david@octobus.net> |
---|---|
date | Sun, 05 Jun 2022 07:16:29 +0200 |
parents | ef0b0f94d2e5 |
children | 493034cc3265 |
line wrap: on
line source
#!/usr/bin/env python3 # compare various algorithm variants for a given case # # search-discovery-case REPO LOCAL_CASE REMOTE_CASE # # The description for the case input uses the same format as the ouput of # search-discovery-case import json import os import subprocess import sys this_script = os.path.abspath(sys.argv[0]) script_name = os.path.basename(this_script) this_dir = os.path.dirname(this_script) hg_dir = os.path.join(this_dir, '..', '..') HG_REPO = os.path.normpath(hg_dir) HG_BIN = os.path.join(HG_REPO, 'hg') SUBSET_PATH = os.path.join(HG_REPO, 'contrib', 'perf-utils', 'subsetmaker.py') CMD_BASE = ( HG_BIN, 'debugdiscovery', '--template', 'json', '--config', 'extensions.subset=%s' % SUBSET_PATH, ) # --old # --nonheads # # devel.discovery.exchange-heads=True # devel.discovery.grow-sample=True # devel.discovery.grow-sample.dynamic=True VARIANTS = { 'tree-discovery': ('--old',), 'set-discovery-basic': ( '--config', 'devel.discovery.exchange-heads=no', '--config', 'devel.discovery.grow-sample=no', '--config', 'devel.discovery.grow-sample.dynamic=no', '--config', 'devel.discovery.randomize=yes', ), 'set-discovery-heads': ( '--config', 'devel.discovery.exchange-heads=yes', '--config', 'devel.discovery.grow-sample=no', '--config', 'devel.discovery.grow-sample.dynamic=no', '--config', 'devel.discovery.randomize=yes', ), 'set-discovery-grow-sample': ( '--config', 'devel.discovery.exchange-heads=yes', '--config', 'devel.discovery.grow-sample=yes', '--config', 'devel.discovery.grow-sample.dynamic=no', '--config', 'devel.discovery.randomize=yes', ), 'set-discovery-dynamic-sample': ( '--config', 'devel.discovery.exchange-heads=yes', '--config', 'devel.discovery.grow-sample=yes', '--config', 'devel.discovery.grow-sample.dynamic=yes', '--config', 'devel.discovery.randomize=yes', ), 'set-discovery-default': ( '--config', 'devel.discovery.randomize=yes', ), } VARIANTS_KEYS = [ 'tree-discovery', 'set-discovery-basic', 'set-discovery-heads', 'set-discovery-grow-sample', 'set-discovery-dynamic-sample', 'set-discovery-default', ] assert set(VARIANTS.keys()) == set(VARIANTS_KEYS) def parse_case(case): case_type, case_args = case.split('-', 1) if case_type == 'file': case_args = (case_args,) else: case_args = tuple(int(x) for x in case_args.split('-')) case = (case_type,) + case_args return case def format_case(case): return '-'.join(str(s) for s in case) def to_revsets(case): t = case[0] if t == 'scratch': return 'not scratch(all(), %d, "%d")' % (case[1], case[2]) elif t == 'randomantichain': return '::randomantichain(all(), "%d")' % case[1] elif t == 'rev': return '::%d' % case[1] elif t == 'file': return '::nodefromfile("%s")' % case[1] else: assert False def compare( repo, local_case, remote_case, display_header=True, display_case=True, ): case = (repo, local_case, remote_case) if display_header: pieces = ['#'] if display_case: pieces += [ "repo", "local-subset", "remote-subset", ] pieces += [ "discovery-variant", "roundtrips", "queries", "revs", "local-heads", "common-heads", "undecided-initial", "undecided-common", "undecided-missing", ] print(*pieces) for variant in VARIANTS_KEYS: res = process(case, VARIANTS[variant]) revs = res["nb-revs"] local_heads = res["nb-head-local"] common_heads = res["nb-common-heads"] roundtrips = res["total-roundtrips"] queries = res["total-queries"] pieces = [] if display_case: pieces += [ repo, format_case(local_case), format_case(remote_case), ] pieces += [ variant, roundtrips, queries, revs, local_heads, common_heads, ] if 'tree-discovery' not in variant: undecided_common = res["nb-ini_und-common"] undecided_missing = res["nb-ini_und-missing"] undecided = undecided_common + undecided_missing pieces += [ undecided, undecided_common, undecided_missing, ] print(*pieces) return 0 def process(case, variant): (repo, left, right) = case cmd = list(CMD_BASE) cmd.append('-R') cmd.append(repo) cmd.append('--local-as-revs') cmd.append(to_revsets(left)) cmd.append('--remote-as-revs') cmd.append(to_revsets(right)) cmd.extend(variant) s = subprocess.Popen(cmd, stdout=subprocess.PIPE) out, err = s.communicate() return json.loads(out)[0] if __name__ == '__main__': argv = sys.argv[:] kwargs = {} # primitive arg parsing if '--no-header' in argv: kwargs['display_header'] = False argv = [a for a in argv if a != '--no-header'] if '--no-case' in argv: kwargs['display_case'] = False argv = [a for a in argv if a != '--no-case'] if len(argv) != 4: usage = f'USAGE: {script_name} REPO LOCAL_CASE REMOTE_CASE' print(usage, file=sys.stderr) sys.exit(128) repo = argv[1] local_case = parse_case(argv[2]) remote_case = parse_case(argv[3]) sys.exit(compare(repo, local_case, remote_case, **kwargs))