Patchwork perf: add a 'perf.all-timing' option to display more than best time

login
register
mail settings
Submitter Boris Feld
Date July 16, 2018, 8:58 a.m.
Message ID <b1591371c449492acb95.1531731481@FB-lair>
Download mbox | patch
Permalink /patch/32854/
State Accepted
Headers show

Comments

Boris Feld - July 16, 2018, 8:58 a.m.
# HG changeset patch
# User Boris Feld <boris.feld@octobus.net>
# Date 1529661762 -3600
#      Fri Jun 22 11:02:42 2018 +0100
# Node ID b1591371c449492acb95e2fe071340ecc673e3bc
# Parent  3700564c63fee7b26ca948e75dee2ea631b1dd4e
# EXP-Topic perf-details
# Available At https://bitbucket.org/octobus/mercurial-devel/
#              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r b1591371c449
perf: add a 'perf.all-timing' option to display more than best time

Minimal time is a useful information, but it is useful to have a wider view on
the performance picture.
Yuya Nishihara - July 16, 2018, 9:34 a.m.
On Mon, 16 Jul 2018 10:58:01 +0200, Boris Feld wrote:
> # HG changeset patch
> # User Boris Feld <boris.feld@octobus.net>
> # Date 1529661762 -3600
> #      Fri Jun 22 11:02:42 2018 +0100
> # Node ID b1591371c449492acb95e2fe071340ecc673e3bc
> # Parent  3700564c63fee7b26ca948e75dee2ea631b1dd4e
> # EXP-Topic perf-details
> # Available At https://bitbucket.org/octobus/mercurial-devel/
> #              hg pull https://bitbucket.org/octobus/mercurial-devel/ -r b1591371c449
> perf: add a 'perf.all-timing' option to display more than best time

Seems fine, queued, thanks.

> +        prefix = ''
> +        if role != 'best':
> +            prefix = '%s.' % role
> +        fm.plain('!')
> +        fm.write(prefix + 'wall', ' wall %f', entry[0])

Nit: prefix + whatever should be a valid symbol (i.e. '.' isn't allowed),
but nobody would care. If we really want to get a structured output, each
display() should be a dict of the same structure.

Patch

diff --git a/contrib/perf.py b/contrib/perf.py
--- a/contrib/perf.py
+++ b/contrib/perf.py
@@ -178,6 +178,9 @@  try:
     configitem('perf', 'parentscount',
         default=mercurial.configitems.dynamicdefault,
     )
+    configitem('perf', 'all-timing',
+        default=mercurial.configitems.dynamicdefault,
+    )
 except (ImportError, AttributeError):
     pass
 
@@ -247,12 +250,15 @@  def gettimer(ui, opts=None):
     # experimental config: perf.stub
     if ui.configbool("perf", "stub", False):
         return functools.partial(stub_timer, fm), fm
-    return functools.partial(_timer, fm), fm
+
+    # experimental config: perf.all-timing
+    displayall = ui.configbool("perf", "all-timing", False)
+    return functools.partial(_timer, fm, displayall=displayall), fm
 
 def stub_timer(fm, func, title=None):
     func()
 
-def _timer(fm, func, title=None):
+def _timer(fm, func, title=None, displayall=False):
     gc.collect()
     results = []
     begin = util.timer()
@@ -277,14 +283,27 @@  def _timer(fm, func, title=None):
         fm.write('title', '! %s\n', title)
     if r:
         fm.write('result', '! result: %s\n', r)
-    m = min(results)
-    fm.plain('!')
-    fm.write('wall', ' wall %f', m[0])
-    fm.write('comb', ' comb %f', m[1] + m[2])
-    fm.write('user', ' user %f', m[1])
-    fm.write('sys',  ' sys %f', m[2])
-    fm.write('count',  ' (best of %d)', count)
-    fm.plain('\n')
+    def display(role, entry):
+        prefix = ''
+        if role != 'best':
+            prefix = '%s.' % role
+        fm.plain('!')
+        fm.write(prefix + 'wall', ' wall %f', entry[0])
+        fm.write(prefix + 'comb', ' comb %f', entry[1] + entry[2])
+        fm.write(prefix + 'user', ' user %f', entry[1])
+        fm.write(prefix + 'sys',  ' sys %f', entry[2])
+        fm.write(prefix + 'count',  ' (%s of %d)', role, count)
+        fm.plain('\n')
+    results.sort()
+    min_val = results[0]
+    display('best', min_val)
+    if displayall:
+        max_val = results[-1]
+        display('max', max_val)
+        avg = tuple([sum(x) / count for x in zip(*results)])
+        display('avg', avg)
+        median = results[len(results)//2]
+        display('median', median)
 
 # utilities for historical portability
 
diff --git a/tests/test-contrib-perf.t b/tests/test-contrib-perf.t
--- a/tests/test-contrib-perf.t
+++ b/tests/test-contrib-perf.t
@@ -175,7 +175,24 @@  perfstatus
   $ hg perfwalk
   $ hg perfparents
 
+test actual output
+------------------
+
+normal output:
+
+  $ hg perfheads --config perf.stub=no
+  ! wall * comb * user * sys * (best of *) (glob)
+
+detailed output:
+
+  $ hg perfheads --config perf.all-timing=yes --config perf.stub=no
+  ! wall * comb * user * sys * (best of *) (glob)
+  ! wall * comb * user * sys * (max of *) (glob)
+  ! wall * comb * user * sys * (avg of *) (glob)
+  ! wall * comb * user * sys * (median of *) (glob)
+
 Check perf.py for historical portability
+----------------------------------------
 
   $ cd "$TESTDIR/.."