Mercurial > public > mercurial-scm > hg-stable
comparison contrib/perf-utils/perf-revlog-write-plot.py @ 40971:abd7b75e80bc
contrib: provide a small script that draw performance plot
We have been using this script to look into the result of various runs of the
`hg perfrevlogwrite` command. It seems useful enough to be shared more widely.
author | Paul Morelle <paul.morelle@octobus.net> |
---|---|
date | Fri, 14 Dec 2018 18:15:19 +0100 |
parents | |
children | c3e5ce3a9483 |
comparison
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)) |