contrib/revsetbenchmarks.py
changeset 43076 2372284d9457
parent 41545 fbb43514f342
child 45830 c102b704edb5
--- a/contrib/revsetbenchmarks.py	Sat Oct 05 10:29:34 2019 -0400
+++ b/contrib/revsetbenchmarks.py	Sun Oct 06 09:45:02 2019 -0400
@@ -16,9 +16,20 @@
 import subprocess
 import sys
 
-DEFAULTVARIANTS = ['plain', 'min', 'max', 'first', 'last',
-                   'reverse', 'reverse+first', 'reverse+last',
-                   'sort', 'sort+first', 'sort+last']
+DEFAULTVARIANTS = [
+    'plain',
+    'min',
+    'max',
+    'first',
+    'last',
+    'reverse',
+    'reverse+first',
+    'reverse+last',
+    'sort',
+    'sort+first',
+    'sort+last',
+]
+
 
 def check_output(*args, **kwargs):
     kwargs.setdefault('stderr', subprocess.PIPE)
@@ -29,14 +40,16 @@
         raise subprocess.CalledProcessError(proc.returncode, ' '.join(args[0]))
     return output
 
+
 def update(rev):
     """update the repo to a revision"""
     try:
         subprocess.check_call(['hg', 'update', '--quiet', '--check', str(rev)])
-        check_output(['make', 'local'],
-                     stderr=None)  # suppress output except for error/warning
+        check_output(
+            ['make', 'local'], stderr=None
+        )  # suppress output except for error/warning
     except subprocess.CalledProcessError as exc:
-        print('update to revision %s failed, aborting'%rev, file=sys.stderr)
+        print('update to revision %s failed, aborting' % rev, file=sys.stderr)
         sys.exit(exc.returncode)
 
 
@@ -48,11 +61,14 @@
     fullcmd = ['./hg']
     if repo is not None:
         fullcmd += ['-R', repo]
-    fullcmd += ['--config',
-                'extensions.perf=' + os.path.join(contribdir, 'perf.py')]
+    fullcmd += [
+        '--config',
+        'extensions.perf=' + os.path.join(contribdir, 'perf.py'),
+    ]
     fullcmd += cmd
     return check_output(fullcmd, stderr=subprocess.STDOUT)
 
+
 def perf(revset, target=None, contexts=False):
     """run benchmark for this very revset"""
     try:
@@ -64,15 +80,21 @@
         output = hg(args, repo=target)
         return parseoutput(output)
     except subprocess.CalledProcessError as exc:
-        print('abort: cannot run revset benchmark: %s'%exc.cmd, file=sys.stderr)
-        if getattr(exc, 'output', None) is None: # no output before 2.7
+        print(
+            'abort: cannot run revset benchmark: %s' % exc.cmd, file=sys.stderr
+        )
+        if getattr(exc, 'output', None) is None:  # no output before 2.7
             print('(no output)', file=sys.stderr)
         else:
             print(exc.output, file=sys.stderr)
         return None
 
-outputre = re.compile(br'! wall (\d+.\d+) comb (\d+.\d+) user (\d+.\d+) '
-                      br'sys (\d+.\d+) \(best of (\d+)\)')
+
+outputre = re.compile(
+    br'! wall (\d+.\d+) comb (\d+.\d+) user (\d+.\d+) '
+    br'sys (\d+.\d+) \(best of (\d+)\)'
+)
+
 
 def parseoutput(output):
     """parse a textual output into a dict
@@ -85,20 +107,30 @@
         print('abort: invalid output:', file=sys.stderr)
         print(output, file=sys.stderr)
         sys.exit(1)
-    return {'comb': float(match.group(2)),
-            'count': int(match.group(5)),
-            'sys': float(match.group(3)),
-            'user': float(match.group(4)),
-            'wall': float(match.group(1)),
-            }
+    return {
+        'comb': float(match.group(2)),
+        'count': int(match.group(5)),
+        'sys': float(match.group(3)),
+        'user': float(match.group(4)),
+        'wall': float(match.group(1)),
+    }
+
 
 def printrevision(rev):
     """print data about a revision"""
     sys.stdout.write("Revision ")
     sys.stdout.flush()
-    subprocess.check_call(['hg', 'log', '--rev', str(rev), '--template',
-                           '{if(tags, " ({tags})")} '
-                           '{rev}:{node|short}: {desc|firstline}\n'])
+    subprocess.check_call(
+        [
+            'hg',
+            'log',
+            '--rev',
+            str(rev),
+            '--template',
+            '{if(tags, " ({tags})")} ' '{rev}:{node|short}: {desc|firstline}\n',
+        ]
+    )
+
 
 def idxwidth(nbidx):
     """return the max width of number used for index
@@ -107,7 +139,7 @@
     because we start with zero and we'd rather not deal with all the
     extra rounding business that log10 would imply.
     """
-    nbidx -= 1 # starts at 0
+    nbidx -= 1  # starts at 0
     idxwidth = 0
     while nbidx:
         idxwidth += 1
@@ -116,6 +148,7 @@
         idxwidth = 1
     return idxwidth
 
+
 def getfactor(main, other, field, sensitivity=0.05):
     """return the relative factor between values for 'field' in main and other
 
@@ -125,10 +158,11 @@
     if main is not None:
         factor = other[field] / main[field]
     low, high = 1 - sensitivity, 1 + sensitivity
-    if (low < factor < high):
+    if low < factor < high:
         return None
     return factor
 
+
 def formatfactor(factor):
     """format a factor into a 4 char string
 
@@ -155,15 +189,19 @@
             factor //= 0
         return 'x%ix%i' % (factor, order)
 
+
 def formattiming(value):
     """format a value to strictly 8 char, dropping some precision if needed"""
-    if value < 10**7:
+    if value < 10 ** 7:
         return ('%.6f' % value)[:8]
     else:
         # value is HUGE very unlikely to happen (4+ month run)
         return '%i' % value
 
+
 _marker = object()
+
+
 def printresult(variants, idx, data, maxidx, verbose=False, reference=_marker):
     """print a line of result to stdout"""
     mask = '%%0%ii) %%s' % idxwidth(maxidx)
@@ -184,9 +222,10 @@
             out.append(formattiming(data[var]['comb']))
             out.append(formattiming(data[var]['user']))
             out.append(formattiming(data[var]['sys']))
-            out.append('%6d'    % data[var]['count'])
+            out.append('%6d' % data[var]['count'])
     print(mask % (idx, ' '.join(out)))
 
+
 def printheader(variants, maxidx, verbose=False, relative=False):
     header = [' ' * (idxwidth(maxidx) + 1)]
     for var in variants:
@@ -204,12 +243,13 @@
             header.append('%6s' % 'count')
     print(' '.join(header))
 
+
 def getrevs(spec):
     """get the list of rev matched by a revset"""
     try:
         out = check_output(['hg', 'log', '--template={rev}\n', '--rev', spec])
     except subprocess.CalledProcessError as exc:
-        print("abort, can't get revision from %s"%spec, file=sys.stderr)
+        print("abort, can't get revision from %s" % spec, file=sys.stderr)
         sys.exit(exc.returncode)
     return [r for r in out.split() if r]
 
@@ -221,31 +261,44 @@
         revset = '%s(%s)' % (var, revset)
     return revset
 
-helptext="""This script will run multiple variants of provided revsets using
+
+helptext = """This script will run multiple variants of provided revsets using
 different revisions in your mercurial repository. After the benchmark are run
 summary output is provided. Use it to demonstrate speed improvements or pin
 point regressions. Revsets to run are specified in a file (or from stdin), one
 revsets per line. Line starting with '#' will be ignored, allowing insertion of
 comments."""
-parser = optparse.OptionParser(usage="usage: %prog [options] <revs>",
-                               description=helptext)
-parser.add_option("-f", "--file",
-                  help="read revset from FILE (stdin if omitted)",
-                  metavar="FILE")
-parser.add_option("-R", "--repo",
-                  help="run benchmark on REPO", metavar="REPO")
+parser = optparse.OptionParser(
+    usage="usage: %prog [options] <revs>", description=helptext
+)
+parser.add_option(
+    "-f",
+    "--file",
+    help="read revset from FILE (stdin if omitted)",
+    metavar="FILE",
+)
+parser.add_option("-R", "--repo", help="run benchmark on REPO", metavar="REPO")
 
-parser.add_option("-v", "--verbose",
-                  action='store_true',
-                  help="display all timing data (not just best total time)")
+parser.add_option(
+    "-v",
+    "--verbose",
+    action='store_true',
+    help="display all timing data (not just best total time)",
+)
 
-parser.add_option("", "--variants",
-                  default=','.join(DEFAULTVARIANTS),
-                  help="comma separated list of variant to test "
-                       "(eg: plain,min,sorted) (plain = no modification)")
-parser.add_option('', '--contexts',
-                  action='store_true',
-                  help='obtain changectx from results instead of integer revs')
+parser.add_option(
+    "",
+    "--variants",
+    default=','.join(DEFAULTVARIANTS),
+    help="comma separated list of variant to test "
+    "(eg: plain,min,sorted) (plain = no modification)",
+)
+parser.add_option(
+    '',
+    '--contexts',
+    action='store_true',
+    help='obtain changectx from results instead of integer revs',
+)
 
 (options, args) = parser.parse_args()
 
@@ -294,17 +347,20 @@
             data = perf(varrset, target=options.repo, contexts=options.contexts)
             varres[var] = data
         res.append(varres)
-        printresult(variants, idx, varres, len(revsets),
-                    verbose=options.verbose)
+        printresult(
+            variants, idx, varres, len(revsets), verbose=options.verbose
+        )
         sys.stdout.flush()
     print("----------------------------")
 
 
-print("""
+print(
+    """
 
 Result by revset
 ================
-""")
+"""
+)
 
 print('Revision:')
 for idx, rev in enumerate(revs):
@@ -321,7 +377,13 @@
     printheader(variants, len(results), verbose=options.verbose, relative=True)
     ref = None
     for idx, data in enumerate(results):
-        printresult(variants, idx, data[ridx], len(results),
-                    verbose=options.verbose, reference=ref)
+        printresult(
+            variants,
+            idx,
+            data[ridx],
+            len(results),
+            verbose=options.verbose,
+            reference=ref,
+        )
         ref = data[ridx]
     print()