##// END OF EJS Templates
contrib: provide a small script that draw performance plot...
Paul Morelle -
r40994:abd7b75e default
parent child Browse files
Show More
@@ -0,0 +1,125 b''
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))
@@ -1,35 +1,36 b''
1 #require test-repo
1 #require test-repo
2
2
3 $ . "$TESTDIR/helpers-testrepo.sh"
3 $ . "$TESTDIR/helpers-testrepo.sh"
4 $ import_checker="$TESTDIR"/../contrib/import-checker.py
4 $ import_checker="$TESTDIR"/../contrib/import-checker.py
5
5
6 $ cd "$TESTDIR"/..
6 $ cd "$TESTDIR"/..
7
7
8 There are a handful of cases here that require renaming a module so it
8 There are a handful of cases here that require renaming a module so it
9 doesn't overlap with a stdlib module name. There are also some cycles
9 doesn't overlap with a stdlib module name. There are also some cycles
10 here that we should still endeavor to fix, and some cycles will be
10 here that we should still endeavor to fix, and some cycles will be
11 hidden by deduplication algorithm in the cycle detector, so fixing
11 hidden by deduplication algorithm in the cycle detector, so fixing
12 these may expose other cycles.
12 these may expose other cycles.
13
13
14 Known-bad files are excluded by -X as some of them would produce unstable
14 Known-bad files are excluded by -X as some of them would produce unstable
15 outputs, which should be fixed later.
15 outputs, which should be fixed later.
16
16
17 $ testrepohg locate 'set:**.py or grep(r"^#!.*?python")' \
17 $ testrepohg locate 'set:**.py or grep(r"^#!.*?python")' \
18 > 'tests/**.t' \
18 > 'tests/**.t' \
19 > -X hgweb.cgi \
19 > -X hgweb.cgi \
20 > -X setup.py \
20 > -X setup.py \
21 > -X contrib/debugshell.py \
21 > -X contrib/debugshell.py \
22 > -X contrib/hgweb.fcgi \
22 > -X contrib/hgweb.fcgi \
23 > -X contrib/packaging/hg-docker \
23 > -X contrib/packaging/hg-docker \
24 > -X contrib/python-zstandard/ \
24 > -X contrib/python-zstandard/ \
25 > -X contrib/win32/hgwebdir_wsgi.py \
25 > -X contrib/win32/hgwebdir_wsgi.py \
26 > -X contrib/perf-utils/perf-revlog-write-plot.py \
26 > -X doc/gendoc.py \
27 > -X doc/gendoc.py \
27 > -X doc/hgmanpage.py \
28 > -X doc/hgmanpage.py \
28 > -X i18n/posplit \
29 > -X i18n/posplit \
29 > -X mercurial/thirdparty \
30 > -X mercurial/thirdparty \
30 > -X tests/hypothesishelpers.py \
31 > -X tests/hypothesishelpers.py \
31 > -X tests/test-check-interfaces.py \
32 > -X tests/test-check-interfaces.py \
32 > -X tests/test-demandimport.py \
33 > -X tests/test-demandimport.py \
33 > -X tests/test-imports-checker.t \
34 > -X tests/test-imports-checker.t \
34 > -X tests/test-verify-repo-operations.py \
35 > -X tests/test-verify-repo-operations.py \
35 > | sed 's-\\-/-g' | "$PYTHON" "$import_checker" -
36 > | sed 's-\\-/-g' | "$PYTHON" "$import_checker" -
General Comments 0
You need to be logged in to leave comments. Login now