contrib/perf-utils/perf-revlog-write-plot.py
changeset 40971 abd7b75e80bc
child 41190 c3e5ce3a9483
equal deleted inserted replaced
40970:f960c51eebf3 40971:abd7b75e80bc
       
     1 #!/usr/bin/env python
       
     2 #
       
     3 #  Copyright 2018 Paul Morelle <Paul.Morelle@octobus.net>
       
     4 #
       
     5 # This software may be used and distributed according to the terms of the
       
     6 # GNU General Public License version 2 or any later version.
       
     7 #
       
     8 # This script use the output of `hg perfrevlogwrite -T json --details` to draw
       
     9 # various plot related to write performance in a revlog
       
    10 #
       
    11 # usage: perf-revlog-write-plot.py details.json
       
    12 from __future__ import absolute_import, print_function
       
    13 import json
       
    14 import re
       
    15 
       
    16 import numpy as np
       
    17 import scipy.signal
       
    18 
       
    19 from matplotlib import (
       
    20     pyplot as plt,
       
    21     ticker as mticker,
       
    22 )
       
    23 
       
    24 
       
    25 def plot(data):
       
    26     items = {}
       
    27     re_title = re.compile(r'^revisions #\d+ of \d+, rev (\d+)$')
       
    28     for item in data:
       
    29         m = re_title.match(item['title'])
       
    30         if m is None:
       
    31             continue
       
    32 
       
    33         rev = int(m.group(1))
       
    34         items[rev] = item
       
    35 
       
    36     min_rev = min(items.keys())
       
    37     max_rev = max(items.keys())
       
    38     ary = np.empty((2, max_rev - min_rev + 1))
       
    39     for rev, item in items.items():
       
    40         ary[0][rev - min_rev] = rev
       
    41         ary[1][rev - min_rev] = item['wall']
       
    42 
       
    43     fig = plt.figure()
       
    44     comb_plt = fig.add_subplot(211)
       
    45     other_plt = fig.add_subplot(212)
       
    46 
       
    47     comb_plt.plot(ary[0],
       
    48                   np.cumsum(ary[1]),
       
    49                   color='red',
       
    50                   linewidth=1,
       
    51                   label='comb')
       
    52 
       
    53     plots = []
       
    54     p = other_plt.plot(ary[0],
       
    55                        ary[1],
       
    56                        color='red',
       
    57                        linewidth=1,
       
    58                        label='wall')
       
    59     plots.append(p)
       
    60 
       
    61     colors = {
       
    62         10: ('green', 'xkcd:grass green'),
       
    63         100: ('blue', 'xkcd:bright blue'),
       
    64         1000: ('purple', 'xkcd:dark pink'),
       
    65     }
       
    66     for n, color in colors.items():
       
    67         avg_n = np.convolve(ary[1], np.full(n, 1. / n), 'valid')
       
    68         p = other_plt.plot(ary[0][n - 1:],
       
    69                            avg_n,
       
    70                            color=color[0],
       
    71                            linewidth=1,
       
    72                            label='avg time last %d' % n)
       
    73         plots.append(p)
       
    74 
       
    75         med_n = scipy.signal.medfilt(ary[1], n + 1)
       
    76         p = other_plt.plot(ary[0],
       
    77                            med_n,
       
    78                            color=color[1],
       
    79                            linewidth=1,
       
    80                            label='median time last %d' % n)
       
    81         plots.append(p)
       
    82 
       
    83     formatter = mticker.ScalarFormatter()
       
    84     formatter.set_scientific(False)
       
    85     formatter.set_useOffset(False)
       
    86 
       
    87     comb_plt.grid()
       
    88     comb_plt.xaxis.set_major_formatter(formatter)
       
    89     comb_plt.legend()
       
    90 
       
    91     other_plt.grid()
       
    92     other_plt.xaxis.set_major_formatter(formatter)
       
    93     leg = other_plt.legend()
       
    94     leg2plot = {}
       
    95     for legline, plot in zip(leg.get_lines(), plots):
       
    96         legline.set_picker(5)
       
    97         leg2plot[legline] = plot
       
    98 
       
    99     def onpick(event):
       
   100         legline = event.artist
       
   101         plot = leg2plot[legline]
       
   102         visible = not plot[0].get_visible()
       
   103         for l in plot:
       
   104             l.set_visible(visible)
       
   105 
       
   106         if visible:
       
   107             legline.set_alpha(1.0)
       
   108         else:
       
   109             legline.set_alpha(0.2)
       
   110         fig.canvas.draw()
       
   111     fig.canvas.mpl_connect('pick_event', onpick)
       
   112 
       
   113     plt.show()
       
   114 
       
   115 
       
   116 if __name__ == '__main__':
       
   117     import sys
       
   118 
       
   119     if len(sys.argv) > 1:
       
   120         print('reading from %r' % sys.argv[1])
       
   121         with open(sys.argv[1], 'r') as fp:
       
   122             plot(json.load(fp))
       
   123     else:
       
   124         print('reading from stdin')
       
   125         plot(json.load(sys.stdin))