Patchwork perf: support -T for every perf commands

login
register
mail settings
Submitter Pierre-Yves David
Date June 9, 2015, 10:35 p.m.
Message ID <76eb548e55a55d74cf7f.1433889353@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/9575/
State Accepted
Headers show

Comments

Pierre-Yves David - June 9, 2015, 10:35 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1433888327 25200
#      Tue Jun 09 15:18:47 2015 -0700
# Node ID 76eb548e55a55d74cf7ff83b18d11f9443bbb4f4
# Parent  ad14fb602e5e54e5432fbc776dd5d1bad63f1f68
perf: support -T for every perf commands

We are already building a formatter, we can not pass him option the official
way.
Augie Fackler - June 10, 2015, 2:27 p.m.
On Tue, Jun 09, 2015 at 03:35:53PM -0700, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1433888327 25200
> #      Tue Jun 09 15:18:47 2015 -0700
> # Node ID 76eb548e55a55d74cf7ff83b18d11f9443bbb4f4
> # Parent  ad14fb602e5e54e5432fbc776dd5d1bad63f1f68
> perf: support -T for every perf commands

queued, thanks

>
> We are already building a formatter, we can not pass him option the official
> way.
>
> diff --git a/contrib/perf.py b/contrib/perf.py
> --- a/contrib/perf.py
> +++ b/contrib/perf.py
> @@ -4,10 +4,12 @@
>  from mercurial import cmdutil, scmutil, util, commands, obsolete
>  from mercurial import repoview, branchmap, merge, copies
>  import time, os, sys
>  import functools
>
> +formatteropts = commands.formatteropts
> +
>  cmdtable = {}
>  command = cmdutil.command(cmdtable)
>
>  def gettimer(ui, opts=None):
>      """return a timer function and formatter: (timer, formatter)
> @@ -58,13 +60,13 @@ def _timer(fm, func, title=None):
>      fm.write('user', ' user %f', m[1])
>      fm.write('sys',  ' sys %f', m[2])
>      fm.write('count',  ' (best of %d)', count)
>      fm.plain('\n')
>
> -@command('perfwalk')
> -def perfwalk(ui, repo, *pats):
> -    timer, fm = gettimer(ui)
> +@command('perfwalk', formatteropts)
> +def perfwalk(ui, repo, *pats, **opts):
> +    timer, fm = gettimer(ui, opts)
>      try:
>          m = scmutil.match(repo[None], pats, {})
>          timer(lambda: len(list(repo.dirstate.walk(m, [], True, False))))
>      except Exception:
>          try:
> @@ -72,31 +74,31 @@ def perfwalk(ui, repo, *pats):
>              timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)]))
>          except Exception:
>              timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
>      fm.end()
>
> -@command('perfannotate')
> -def perfannotate(ui, repo, f):
> -    timer, fm = gettimer(ui)
> +@command('perfannotate', formatteropts)
> +def perfannotate(ui, repo, f, **opts):
> +    timer, fm = gettimer(ui, opts)
>      fc = repo['.'][f]
>      timer(lambda: len(fc.annotate(True)))
>      fm.end()
>
>  @command('perfstatus',
>           [('u', 'unknown', False,
> -           'ask status to look for unknown files')])
> +           'ask status to look for unknown files')] + formatteropts)
>  def perfstatus(ui, repo, **opts):
>      #m = match.always(repo.root, repo.getcwd())
>      #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
>      #                                                False))))
> -    timer, fm = gettimer(ui)
> -    timer(lambda: sum(map(len, repo.status(**opts))))
> +    timer, fm = gettimer(ui, **opts)
> +    timer(lambda: sum(map(len, repo.status(unknown=opts['unknown']))))
>      fm.end()
>
> -@command('perfaddremove')
> -def perfaddremove(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfaddremove', formatteropts)
> +def perfaddremove(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      try:
>          oldquiet = repo.ui.quiet
>          repo.ui.quiet = True
>          matcher = scmutil.match(repo[None])
>          timer(lambda: scmutil.addremove(repo, matcher, "", dry_run=True))
> @@ -111,124 +113,124 @@ def clearcaches(cl):
>      elif util.safehasattr(cl, '_nodecache'):
>          from mercurial.node import nullid, nullrev
>          cl._nodecache = {nullid: nullrev}
>          cl._nodepos = None
>
> -@command('perfheads')
> -def perfheads(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfheads', formatteropts)
> +def perfheads(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      cl = repo.changelog
>      def d():
>          len(cl.headrevs())
>          clearcaches(cl)
>      timer(d)
>      fm.end()
>
> -@command('perftags')
> -def perftags(ui, repo):
> +@command('perftags', formatteropts)
> +def perftags(ui, repo, **opts):
>      import mercurial.changelog
>      import mercurial.manifest
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      def t():
>          repo.changelog = mercurial.changelog.changelog(repo.svfs)
>          repo.manifest = mercurial.manifest.manifest(repo.svfs)
>          repo._tags = None
>          return len(repo.tags())
>      timer(t)
>      fm.end()
>
> -@command('perfancestors')
> -def perfancestors(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfancestors', formatteropts)
> +def perfancestors(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      heads = repo.changelog.headrevs()
>      def d():
>          for a in repo.changelog.ancestors(heads):
>              pass
>      timer(d)
>      fm.end()
>
> -@command('perfancestorset')
> -def perfancestorset(ui, repo, revset):
> -    timer, fm = gettimer(ui)
> +@command('perfancestorset', formatteropts)
> +def perfancestorset(ui, repo, revset, **opts):
> +    timer, fm = gettimer(ui, opts)
>      revs = repo.revs(revset)
>      heads = repo.changelog.headrevs()
>      def d():
>          s = repo.changelog.ancestors(heads)
>          for rev in revs:
>              rev in s
>      timer(d)
>      fm.end()
>
> -@command('perfdirs')
> -def perfdirs(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfdirs', formatteropts)
> +def perfdirs(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      dirstate = repo.dirstate
>      'a' in dirstate
>      def d():
>          dirstate.dirs()
>          del dirstate._dirs
>      timer(d)
>      fm.end()
>
> -@command('perfdirstate')
> -def perfdirstate(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfdirstate', formatteropts)
> +def perfdirstate(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      "a" in repo.dirstate
>      def d():
>          repo.dirstate.invalidate()
>          "a" in repo.dirstate
>      timer(d)
>      fm.end()
>
> -@command('perfdirstatedirs')
> -def perfdirstatedirs(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfdirstatedirs', formatteropts)
> +def perfdirstatedirs(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      "a" in repo.dirstate
>      def d():
>          "a" in repo.dirstate._dirs
>          del repo.dirstate._dirs
>      timer(d)
>      fm.end()
>
> -@command('perffilefoldmap')
> -def perffilefoldmap(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfdirstatefoldmap', formatteropts)
> +def perffilefoldmap(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      dirstate = repo.dirstate
>      'a' in dirstate
>      def d():
>          dirstate._filefoldmap.get('a')
>          del dirstate._filefoldmap
>      timer(d)
>      fm.end()
>
> -@command('perfdirfoldmap')
> -def perfdirfoldmap(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfdirfoldmap', formatteropts)
> +def perfdirfoldmap(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      dirstate = repo.dirstate
>      'a' in dirstate
>      def d():
>          dirstate._dirfoldmap.get('a')
>          del dirstate._dirfoldmap
>          del dirstate._dirs
>      timer(d)
>      fm.end()
>
> -@command('perfdirstatewrite')
> -def perfdirstatewrite(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfdirstatewrite', formatteropts)
> +def perfdirstatewrite(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      ds = repo.dirstate
>      "a" in ds
>      def d():
>          ds._dirty = True
>          ds.write()
>      timer(d)
>      fm.end()
>
>  @command('perfmergecalculate',
> -         [('r', 'rev', '.', 'rev to merge against')])
> -def perfmergecalculate(ui, repo, rev):
> -    timer, fm = gettimer(ui)
> +         [('r', 'rev', '.', 'rev to merge against')] + formatteropts)
> +def perfmergecalculate(ui, repo, rev, **opts):
> +    timer, fm = gettimer(ui, opts)
>      wctx = repo[None]
>      rctx = scmutil.revsingle(repo, rev, rev)
>      ancestor = wctx.ancestor(rctx)
>      # we don't want working dir files to be stat'd in the benchmark, so prime
>      # that cache
> @@ -240,107 +242,111 @@ def perfmergecalculate(ui, repo, rev):
>                                 acceptremote=True)
>      timer(d)
>      fm.end()
>
>  @command('perfpathcopies', [], "REV REV")
> -def perfpathcopies(ui, repo, rev1, rev2):
> -    timer, fm = gettimer(ui)
> +def perfpathcopies(ui, repo, rev1, rev2, **opts):
> +    timer, fm = gettimer(ui, opts)
>      ctx1 = scmutil.revsingle(repo, rev1, rev1)
>      ctx2 = scmutil.revsingle(repo, rev2, rev2)
>      def d():
>          copies.pathcopies(ctx1, ctx2)
>      timer(d)
>      fm.end()
>
>  @command('perfmanifest', [], 'REV')
> -def perfmanifest(ui, repo, rev):
> -    timer, fm = gettimer(ui)
> +def perfmanifest(ui, repo, rev, **opts):
> +    timer, fm = gettimer(ui, opts)
>      ctx = scmutil.revsingle(repo, rev, rev)
>      t = ctx.manifestnode()
>      def d():
>          repo.manifest._mancache.clear()
>          repo.manifest._cache = None
>          repo.manifest.read(t)
>      timer(d)
>      fm.end()
>
> -@command('perfchangeset')
> -def perfchangeset(ui, repo, rev):
> -    timer, fm = gettimer(ui)
> +@command('perfchangeset', formatteropts)
> +def perfchangeset(ui, repo, rev, **opts):
> +    timer, fm = gettimer(ui, opts)
>      n = repo[rev].node()
>      def d():
>          repo.changelog.read(n)
>          #repo.changelog._cache = None
>      timer(d)
>      fm.end()
>
> -@command('perfindex')
> -def perfindex(ui, repo):
> +@command('perfindex', formatteropts)
> +def perfindex(ui, repo, **opts):
>      import mercurial.revlog
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
>      n = repo["tip"].node()
>      def d():
>          cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
>          cl.rev(n)
>      timer(d)
>      fm.end()
>
> -@command('perfstartup')
> -def perfstartup(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfstartup', formatteropts)
> +def perfstartup(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      cmd = sys.argv[0]
>      def d():
>          os.system("HGRCPATH= %s version -q > /dev/null" % cmd)
>      timer(d)
>      fm.end()
>
> -@command('perfparents')
> -def perfparents(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfparents', formatteropts)
> +def perfparents(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      nl = [repo.changelog.node(i) for i in xrange(1000)]
>      def d():
>          for n in nl:
>              repo.changelog.parents(n)
>      timer(d)
>      fm.end()
>
> -@command('perfctxfiles')
> -def perfparents(ui, repo, x):
> +@command('perfctxfiles', formatteropts)
> +def perfparents(ui, repo, x, **opts):
>      x = int(x)
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      def d():
>          len(repo[x].files())
>      timer(d)
>      fm.end()
>
> -@command('perfrawfiles')
> -def perfparents(ui, repo, x):
> +@command('perfrawfiles', formatteropts)
> +def perfparents(ui, repo, x, **opts):
>      x = int(x)
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      cl = repo.changelog
>      def d():
>          len(cl.read(x)[3])
>      timer(d)
>      fm.end()
>
> -@command('perflookup')
> -def perflookup(ui, repo, rev):
> -    timer, fm = gettimer(ui)
> +@command('perflookup', formatteropts)
> +def perflookup(ui, repo, rev, **opts):
> +    timer, fm = gettimer(ui, opts)
> +
> +@command('perflookup', formatteropts)
> +def perflookup(ui, repo, rev, **opts):
> +    timer, fm = gettimer(ui, opts)
>      timer(lambda: len(repo.lookup(rev)))
>      fm.end()
>
> -@command('perfrevrange')
> -def perfrevrange(ui, repo, *specs):
> -    timer, fm = gettimer(ui)
> +@command('perfrevrange', formatteropts)
> +def perfrevrange(ui, repo, *specs, **opts):
> +    timer, fm = gettimer(ui, opts)
>      revrange = scmutil.revrange
>      timer(lambda: len(revrange(repo, specs)))
>      fm.end()
>
> -@command('perfnodelookup')
> -def perfnodelookup(ui, repo, rev):
> -    timer, fm = gettimer(ui)
> +@command('perfnodelookup', formatteropts)
> +def perfnodelookup(ui, repo, rev, **opts):
> +    timer, fm = gettimer(ui, opts)
>      import mercurial.revlog
>      mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
>      n = repo[rev].node()
>      cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
>      def d():
> @@ -348,84 +354,84 @@ def perfnodelookup(ui, repo, rev):
>          clearcaches(cl)
>      timer(d)
>      fm.end()
>
>  @command('perflog',
> -         [('', 'rename', False, 'ask log to follow renames')])
> +         [('', 'rename', False, 'ask log to follow renames')] + formatteropts)
>  def perflog(ui, repo, **opts):
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      ui.pushbuffer()
>      timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
>                                 copies=opts.get('rename')))
>      ui.popbuffer()
>      fm.end()
>
> -@command('perfmoonwalk')
> -def perfmoonwalk(ui, repo):
> +@command('perfmoonwalk', formatteropts)
> +def perfmoonwalk(ui, repo, **opts):
>      """benchmark walking the changelog backwards
>
>      This also loads the changelog data for each revision in the changelog.
>      """
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      def moonwalk():
>          for i in xrange(len(repo), -1, -1):
>              ctx = repo[i]
>              ctx.branch() # read changelog data (in addition to the index)
>      timer(moonwalk)
>      fm.end()
>
> -@command('perftemplating')
> -def perftemplating(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perftemplating', formatteropts)
> +def perftemplating(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      ui.pushbuffer()
>      timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
>                                 template='{date|shortdate} [{rev}:{node|short}]'
>                                 ' {author|person}: {desc|firstline}\n'))
>      ui.popbuffer()
>      fm.end()
>
> -@command('perfcca')
> -def perfcca(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perfcca', formatteropts)
> +def perfcca(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
>      fm.end()
>
> -@command('perffncacheload')
> -def perffncacheload(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perffncacheload', formatteropts)
> +def perffncacheload(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      s = repo.store
>      def d():
>          s.fncache._load()
>      timer(d)
>      fm.end()
>
> -@command('perffncachewrite')
> -def perffncachewrite(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perffncachewrite', formatteropts)
> +def perffncachewrite(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      s = repo.store
>      s.fncache._load()
>      def d():
>          s.fncache._dirty = True
>          s.fncache.write()
>      timer(d)
>      fm.end()
>
> -@command('perffncacheencode')
> -def perffncacheencode(ui, repo):
> -    timer, fm = gettimer(ui)
> +@command('perffncacheencode', formatteropts)
> +def perffncacheencode(ui, repo, **opts):
> +    timer, fm = gettimer(ui, opts)
>      s = repo.store
>      s.fncache._load()
>      def d():
>          for p in s.fncache.entries:
>              s.encode(p)
>      timer(d)
>      fm.end()
>
> -@command('perfdiffwd')
> -def perfdiffwd(ui, repo):
> +@command('perfdiffwd', formatteropts)
> +def perfdiffwd(ui, repo, **opts):
>      """Profile diff of working directory changes"""
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      options = {
>          'w': 'ignore_all_space',
>          'b': 'ignore_space_change',
>          'B': 'ignore_blank_lines',
>          }
> @@ -439,14 +445,14 @@ def perfdiffwd(ui, repo):
>          title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
>          timer(d, title)
>      fm.end()
>
>  @command('perfrevlog',
> -         [('d', 'dist', 100, 'distance between the revisions')],
> +         [('d', 'dist', 100, 'distance between the revisions')] + formatteropts,
>           "[INDEXFILE]")
>  def perfrevlog(ui, repo, file_, **opts):
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      from mercurial import revlog
>      dist = opts['dist']
>      def d():
>          r = revlog.revlog(lambda fn: open(fn, 'rb'), file_)
>          for x in xrange(0, len(r), dist):
> @@ -454,32 +460,32 @@ def perfrevlog(ui, repo, file_, **opts):
>
>      timer(d)
>      fm.end()
>
>  @command('perfrevset',
> -         [('C', 'clear', False, 'clear volatile cache between each call.')],
> -         "REVSET")
> -def perfrevset(ui, repo, expr, clear=False):
> +         [('C', 'clear', False, 'clear volatile cache between each call.')]
> +         + formatteropts, "REVSET")
> +def perfrevset(ui, repo, expr, clear=False, **opts):
>      """benchmark the execution time of a revset
>
>      Use the --clean option if need to evaluate the impact of build volatile
>      revisions set cache on the revset execution. Volatile cache hold filtered
>      and obsolete related cache."""
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      def d():
>          if clear:
>              repo.invalidatevolatilesets()
>          for r in repo.revs(expr): pass
>      timer(d)
>      fm.end()
>
> -@command('perfvolatilesets')
> -def perfvolatilesets(ui, repo, *names):
> +@command('perfvolatilesets', formatteropts)
> +def perfvolatilesets(ui, repo, *names, **opts):
>      """benchmark the computation of various volatile set
>
>      Volatile set computes element related to filtering and obsolescence."""
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      repo = repo.unfiltered()
>
>      def getobs(name):
>          def d():
>              repo.invalidatevolatilesets()
> @@ -508,17 +514,17 @@ def perfvolatilesets(ui, repo, *names):
>      fm.end()
>
>  @command('perfbranchmap',
>           [('f', 'full', False,
>             'Includes build time of subset'),
> -         ])
> -def perfbranchmap(ui, repo, full=False):
> +         ] + formatteropts)
> +def perfbranchmap(ui, repo, full=False, **opts):
>      """benchmark the update of a branchmap
>
>      This benchmarks the full repo.branchmap() call with read and write disabled
>      """
> -    timer, fm = gettimer(ui)
> +    timer, fm = gettimer(ui, opts)
>      def getbranchmap(filtername):
>          """generate a benchmark function for the filtername"""
>          if filtername is None:
>              view = repo
>          else:
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> https://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -4,10 +4,12 @@ 
 from mercurial import cmdutil, scmutil, util, commands, obsolete
 from mercurial import repoview, branchmap, merge, copies
 import time, os, sys
 import functools
 
+formatteropts = commands.formatteropts
+
 cmdtable = {}
 command = cmdutil.command(cmdtable)
 
 def gettimer(ui, opts=None):
     """return a timer function and formatter: (timer, formatter)
@@ -58,13 +60,13 @@  def _timer(fm, func, title=None):
     fm.write('user', ' user %f', m[1])
     fm.write('sys',  ' sys %f', m[2])
     fm.write('count',  ' (best of %d)', count)
     fm.plain('\n')
 
-@command('perfwalk')
-def perfwalk(ui, repo, *pats):
-    timer, fm = gettimer(ui)
+@command('perfwalk', formatteropts)
+def perfwalk(ui, repo, *pats, **opts):
+    timer, fm = gettimer(ui, opts)
     try:
         m = scmutil.match(repo[None], pats, {})
         timer(lambda: len(list(repo.dirstate.walk(m, [], True, False))))
     except Exception:
         try:
@@ -72,31 +74,31 @@  def perfwalk(ui, repo, *pats):
             timer(lambda: len([b for a, b, c in repo.dirstate.statwalk([], m)]))
         except Exception:
             timer(lambda: len(list(cmdutil.walk(repo, pats, {}))))
     fm.end()
 
-@command('perfannotate')
-def perfannotate(ui, repo, f):
-    timer, fm = gettimer(ui)
+@command('perfannotate', formatteropts)
+def perfannotate(ui, repo, f, **opts):
+    timer, fm = gettimer(ui, opts)
     fc = repo['.'][f]
     timer(lambda: len(fc.annotate(True)))
     fm.end()
 
 @command('perfstatus',
          [('u', 'unknown', False,
-           'ask status to look for unknown files')])
+           'ask status to look for unknown files')] + formatteropts)
 def perfstatus(ui, repo, **opts):
     #m = match.always(repo.root, repo.getcwd())
     #timer(lambda: sum(map(len, repo.dirstate.status(m, [], False, False,
     #                                                False))))
-    timer, fm = gettimer(ui)
-    timer(lambda: sum(map(len, repo.status(**opts))))
+    timer, fm = gettimer(ui, **opts)
+    timer(lambda: sum(map(len, repo.status(unknown=opts['unknown']))))
     fm.end()
 
-@command('perfaddremove')
-def perfaddremove(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfaddremove', formatteropts)
+def perfaddremove(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     try:
         oldquiet = repo.ui.quiet
         repo.ui.quiet = True
         matcher = scmutil.match(repo[None])
         timer(lambda: scmutil.addremove(repo, matcher, "", dry_run=True))
@@ -111,124 +113,124 @@  def clearcaches(cl):
     elif util.safehasattr(cl, '_nodecache'):
         from mercurial.node import nullid, nullrev
         cl._nodecache = {nullid: nullrev}
         cl._nodepos = None
 
-@command('perfheads')
-def perfheads(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfheads', formatteropts)
+def perfheads(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     cl = repo.changelog
     def d():
         len(cl.headrevs())
         clearcaches(cl)
     timer(d)
     fm.end()
 
-@command('perftags')
-def perftags(ui, repo):
+@command('perftags', formatteropts)
+def perftags(ui, repo, **opts):
     import mercurial.changelog
     import mercurial.manifest
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     def t():
         repo.changelog = mercurial.changelog.changelog(repo.svfs)
         repo.manifest = mercurial.manifest.manifest(repo.svfs)
         repo._tags = None
         return len(repo.tags())
     timer(t)
     fm.end()
 
-@command('perfancestors')
-def perfancestors(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfancestors', formatteropts)
+def perfancestors(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     heads = repo.changelog.headrevs()
     def d():
         for a in repo.changelog.ancestors(heads):
             pass
     timer(d)
     fm.end()
 
-@command('perfancestorset')
-def perfancestorset(ui, repo, revset):
-    timer, fm = gettimer(ui)
+@command('perfancestorset', formatteropts)
+def perfancestorset(ui, repo, revset, **opts):
+    timer, fm = gettimer(ui, opts)
     revs = repo.revs(revset)
     heads = repo.changelog.headrevs()
     def d():
         s = repo.changelog.ancestors(heads)
         for rev in revs:
             rev in s
     timer(d)
     fm.end()
 
-@command('perfdirs')
-def perfdirs(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfdirs', formatteropts)
+def perfdirs(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     dirstate = repo.dirstate
     'a' in dirstate
     def d():
         dirstate.dirs()
         del dirstate._dirs
     timer(d)
     fm.end()
 
-@command('perfdirstate')
-def perfdirstate(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfdirstate', formatteropts)
+def perfdirstate(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     "a" in repo.dirstate
     def d():
         repo.dirstate.invalidate()
         "a" in repo.dirstate
     timer(d)
     fm.end()
 
-@command('perfdirstatedirs')
-def perfdirstatedirs(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfdirstatedirs', formatteropts)
+def perfdirstatedirs(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     "a" in repo.dirstate
     def d():
         "a" in repo.dirstate._dirs
         del repo.dirstate._dirs
     timer(d)
     fm.end()
 
-@command('perffilefoldmap')
-def perffilefoldmap(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfdirstatefoldmap', formatteropts)
+def perffilefoldmap(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     dirstate = repo.dirstate
     'a' in dirstate
     def d():
         dirstate._filefoldmap.get('a')
         del dirstate._filefoldmap
     timer(d)
     fm.end()
 
-@command('perfdirfoldmap')
-def perfdirfoldmap(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfdirfoldmap', formatteropts)
+def perfdirfoldmap(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     dirstate = repo.dirstate
     'a' in dirstate
     def d():
         dirstate._dirfoldmap.get('a')
         del dirstate._dirfoldmap
         del dirstate._dirs
     timer(d)
     fm.end()
 
-@command('perfdirstatewrite')
-def perfdirstatewrite(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfdirstatewrite', formatteropts)
+def perfdirstatewrite(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     ds = repo.dirstate
     "a" in ds
     def d():
         ds._dirty = True
         ds.write()
     timer(d)
     fm.end()
 
 @command('perfmergecalculate',
-         [('r', 'rev', '.', 'rev to merge against')])
-def perfmergecalculate(ui, repo, rev):
-    timer, fm = gettimer(ui)
+         [('r', 'rev', '.', 'rev to merge against')] + formatteropts)
+def perfmergecalculate(ui, repo, rev, **opts):
+    timer, fm = gettimer(ui, opts)
     wctx = repo[None]
     rctx = scmutil.revsingle(repo, rev, rev)
     ancestor = wctx.ancestor(rctx)
     # we don't want working dir files to be stat'd in the benchmark, so prime
     # that cache
@@ -240,107 +242,111 @@  def perfmergecalculate(ui, repo, rev):
                                acceptremote=True)
     timer(d)
     fm.end()
 
 @command('perfpathcopies', [], "REV REV")
-def perfpathcopies(ui, repo, rev1, rev2):
-    timer, fm = gettimer(ui)
+def perfpathcopies(ui, repo, rev1, rev2, **opts):
+    timer, fm = gettimer(ui, opts)
     ctx1 = scmutil.revsingle(repo, rev1, rev1)
     ctx2 = scmutil.revsingle(repo, rev2, rev2)
     def d():
         copies.pathcopies(ctx1, ctx2)
     timer(d)
     fm.end()
 
 @command('perfmanifest', [], 'REV')
-def perfmanifest(ui, repo, rev):
-    timer, fm = gettimer(ui)
+def perfmanifest(ui, repo, rev, **opts):
+    timer, fm = gettimer(ui, opts)
     ctx = scmutil.revsingle(repo, rev, rev)
     t = ctx.manifestnode()
     def d():
         repo.manifest._mancache.clear()
         repo.manifest._cache = None
         repo.manifest.read(t)
     timer(d)
     fm.end()
 
-@command('perfchangeset')
-def perfchangeset(ui, repo, rev):
-    timer, fm = gettimer(ui)
+@command('perfchangeset', formatteropts)
+def perfchangeset(ui, repo, rev, **opts):
+    timer, fm = gettimer(ui, opts)
     n = repo[rev].node()
     def d():
         repo.changelog.read(n)
         #repo.changelog._cache = None
     timer(d)
     fm.end()
 
-@command('perfindex')
-def perfindex(ui, repo):
+@command('perfindex', formatteropts)
+def perfindex(ui, repo, **opts):
     import mercurial.revlog
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
     n = repo["tip"].node()
     def d():
         cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
         cl.rev(n)
     timer(d)
     fm.end()
 
-@command('perfstartup')
-def perfstartup(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfstartup', formatteropts)
+def perfstartup(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     cmd = sys.argv[0]
     def d():
         os.system("HGRCPATH= %s version -q > /dev/null" % cmd)
     timer(d)
     fm.end()
 
-@command('perfparents')
-def perfparents(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfparents', formatteropts)
+def perfparents(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     nl = [repo.changelog.node(i) for i in xrange(1000)]
     def d():
         for n in nl:
             repo.changelog.parents(n)
     timer(d)
     fm.end()
 
-@command('perfctxfiles')
-def perfparents(ui, repo, x):
+@command('perfctxfiles', formatteropts)
+def perfparents(ui, repo, x, **opts):
     x = int(x)
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     def d():
         len(repo[x].files())
     timer(d)
     fm.end()
 
-@command('perfrawfiles')
-def perfparents(ui, repo, x):
+@command('perfrawfiles', formatteropts)
+def perfparents(ui, repo, x, **opts):
     x = int(x)
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     cl = repo.changelog
     def d():
         len(cl.read(x)[3])
     timer(d)
     fm.end()
 
-@command('perflookup')
-def perflookup(ui, repo, rev):
-    timer, fm = gettimer(ui)
+@command('perflookup', formatteropts)
+def perflookup(ui, repo, rev, **opts):
+    timer, fm = gettimer(ui, opts)
+
+@command('perflookup', formatteropts)
+def perflookup(ui, repo, rev, **opts):
+    timer, fm = gettimer(ui, opts)
     timer(lambda: len(repo.lookup(rev)))
     fm.end()
 
-@command('perfrevrange')
-def perfrevrange(ui, repo, *specs):
-    timer, fm = gettimer(ui)
+@command('perfrevrange', formatteropts)
+def perfrevrange(ui, repo, *specs, **opts):
+    timer, fm = gettimer(ui, opts)
     revrange = scmutil.revrange
     timer(lambda: len(revrange(repo, specs)))
     fm.end()
 
-@command('perfnodelookup')
-def perfnodelookup(ui, repo, rev):
-    timer, fm = gettimer(ui)
+@command('perfnodelookup', formatteropts)
+def perfnodelookup(ui, repo, rev, **opts):
+    timer, fm = gettimer(ui, opts)
     import mercurial.revlog
     mercurial.revlog._prereadsize = 2**24 # disable lazy parser in old hg
     n = repo[rev].node()
     cl = mercurial.revlog.revlog(repo.svfs, "00changelog.i")
     def d():
@@ -348,84 +354,84 @@  def perfnodelookup(ui, repo, rev):
         clearcaches(cl)
     timer(d)
     fm.end()
 
 @command('perflog',
-         [('', 'rename', False, 'ask log to follow renames')])
+         [('', 'rename', False, 'ask log to follow renames')] + formatteropts)
 def perflog(ui, repo, **opts):
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     ui.pushbuffer()
     timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
                                copies=opts.get('rename')))
     ui.popbuffer()
     fm.end()
 
-@command('perfmoonwalk')
-def perfmoonwalk(ui, repo):
+@command('perfmoonwalk', formatteropts)
+def perfmoonwalk(ui, repo, **opts):
     """benchmark walking the changelog backwards
 
     This also loads the changelog data for each revision in the changelog.
     """
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     def moonwalk():
         for i in xrange(len(repo), -1, -1):
             ctx = repo[i]
             ctx.branch() # read changelog data (in addition to the index)
     timer(moonwalk)
     fm.end()
 
-@command('perftemplating')
-def perftemplating(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perftemplating', formatteropts)
+def perftemplating(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     ui.pushbuffer()
     timer(lambda: commands.log(ui, repo, rev=[], date='', user='',
                                template='{date|shortdate} [{rev}:{node|short}]'
                                ' {author|person}: {desc|firstline}\n'))
     ui.popbuffer()
     fm.end()
 
-@command('perfcca')
-def perfcca(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perfcca', formatteropts)
+def perfcca(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate))
     fm.end()
 
-@command('perffncacheload')
-def perffncacheload(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perffncacheload', formatteropts)
+def perffncacheload(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     s = repo.store
     def d():
         s.fncache._load()
     timer(d)
     fm.end()
 
-@command('perffncachewrite')
-def perffncachewrite(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perffncachewrite', formatteropts)
+def perffncachewrite(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     s = repo.store
     s.fncache._load()
     def d():
         s.fncache._dirty = True
         s.fncache.write()
     timer(d)
     fm.end()
 
-@command('perffncacheencode')
-def perffncacheencode(ui, repo):
-    timer, fm = gettimer(ui)
+@command('perffncacheencode', formatteropts)
+def perffncacheencode(ui, repo, **opts):
+    timer, fm = gettimer(ui, opts)
     s = repo.store
     s.fncache._load()
     def d():
         for p in s.fncache.entries:
             s.encode(p)
     timer(d)
     fm.end()
 
-@command('perfdiffwd')
-def perfdiffwd(ui, repo):
+@command('perfdiffwd', formatteropts)
+def perfdiffwd(ui, repo, **opts):
     """Profile diff of working directory changes"""
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     options = {
         'w': 'ignore_all_space',
         'b': 'ignore_space_change',
         'B': 'ignore_blank_lines',
         }
@@ -439,14 +445,14 @@  def perfdiffwd(ui, repo):
         title = 'diffopts: %s' % (diffopt and ('-' + diffopt) or 'none')
         timer(d, title)
     fm.end()
 
 @command('perfrevlog',
-         [('d', 'dist', 100, 'distance between the revisions')],
+         [('d', 'dist', 100, 'distance between the revisions')] + formatteropts,
          "[INDEXFILE]")
 def perfrevlog(ui, repo, file_, **opts):
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     from mercurial import revlog
     dist = opts['dist']
     def d():
         r = revlog.revlog(lambda fn: open(fn, 'rb'), file_)
         for x in xrange(0, len(r), dist):
@@ -454,32 +460,32 @@  def perfrevlog(ui, repo, file_, **opts):
 
     timer(d)
     fm.end()
 
 @command('perfrevset',
-         [('C', 'clear', False, 'clear volatile cache between each call.')],
-         "REVSET")
-def perfrevset(ui, repo, expr, clear=False):
+         [('C', 'clear', False, 'clear volatile cache between each call.')]
+         + formatteropts, "REVSET")
+def perfrevset(ui, repo, expr, clear=False, **opts):
     """benchmark the execution time of a revset
 
     Use the --clean option if need to evaluate the impact of build volatile
     revisions set cache on the revset execution. Volatile cache hold filtered
     and obsolete related cache."""
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     def d():
         if clear:
             repo.invalidatevolatilesets()
         for r in repo.revs(expr): pass
     timer(d)
     fm.end()
 
-@command('perfvolatilesets')
-def perfvolatilesets(ui, repo, *names):
+@command('perfvolatilesets', formatteropts)
+def perfvolatilesets(ui, repo, *names, **opts):
     """benchmark the computation of various volatile set
 
     Volatile set computes element related to filtering and obsolescence."""
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     repo = repo.unfiltered()
 
     def getobs(name):
         def d():
             repo.invalidatevolatilesets()
@@ -508,17 +514,17 @@  def perfvolatilesets(ui, repo, *names):
     fm.end()
 
 @command('perfbranchmap',
          [('f', 'full', False,
            'Includes build time of subset'),
-         ])
-def perfbranchmap(ui, repo, full=False):
+         ] + formatteropts)
+def perfbranchmap(ui, repo, full=False, **opts):
     """benchmark the update of a branchmap
 
     This benchmarks the full repo.branchmap() call with read and write disabled
     """
-    timer, fm = gettimer(ui)
+    timer, fm = gettimer(ui, opts)
     def getbranchmap(filtername):
         """generate a benchmark function for the filtername"""
         if filtername is None:
             view = repo
         else: