perf-revlog-write-plot.py
126 lines
| 3.2 KiB
| text/x-python
|
PythonLexer
Gregory Szorc
|
r46434 | #!/usr/bin/env python3 | ||
Paul Morelle
|
r40994 | # | ||
# Copyright 2018 Paul Morelle <Paul.Morelle@octobus.net> | ||||
# | ||||
# This software may be used and distributed according to the terms of the | ||||
# GNU General Public License version 2 or any later version. | ||||
# | ||||
# This script use the output of `hg perfrevlogwrite -T json --details` to draw | ||||
# various plot related to write performance in a revlog | ||||
# | ||||
# usage: perf-revlog-write-plot.py details.json | ||||
from __future__ import absolute_import, print_function | ||||
import json | ||||
import re | ||||
import numpy as np | ||||
import scipy.signal | ||||
from matplotlib import ( | ||||
pyplot as plt, | ||||
ticker as mticker, | ||||
) | ||||
Boris Feld
|
r41226 | def plot(data, title=None): | ||
Paul Morelle
|
r40994 | items = {} | ||
re_title = re.compile(r'^revisions #\d+ of \d+, rev (\d+)$') | ||||
for item in data: | ||||
m = re_title.match(item['title']) | ||||
if m is None: | ||||
continue | ||||
rev = int(m.group(1)) | ||||
items[rev] = item | ||||
min_rev = min(items.keys()) | ||||
max_rev = max(items.keys()) | ||||
ary = np.empty((2, max_rev - min_rev + 1)) | ||||
for rev, item in items.items(): | ||||
ary[0][rev - min_rev] = rev | ||||
ary[1][rev - min_rev] = item['wall'] | ||||
fig = plt.figure() | ||||
comb_plt = fig.add_subplot(211) | ||||
other_plt = fig.add_subplot(212) | ||||
Augie Fackler
|
r43346 | comb_plt.plot( | ||
ary[0], np.cumsum(ary[1]), color='red', linewidth=1, label='comb' | ||||
) | ||||
Paul Morelle
|
r40994 | |||
plots = [] | ||||
Augie Fackler
|
r43346 | p = other_plt.plot(ary[0], ary[1], color='red', linewidth=1, label='wall') | ||
Paul Morelle
|
r40994 | plots.append(p) | ||
colors = { | ||||
10: ('green', 'xkcd:grass green'), | ||||
100: ('blue', 'xkcd:bright blue'), | ||||
1000: ('purple', 'xkcd:dark pink'), | ||||
} | ||||
for n, color in colors.items(): | ||||
Augie Fackler
|
r43346 | avg_n = np.convolve(ary[1], np.full(n, 1.0 / n), 'valid') | ||
p = other_plt.plot( | ||||
ary[0][n - 1 :], | ||||
avg_n, | ||||
color=color[0], | ||||
linewidth=1, | ||||
label='avg time last %d' % n, | ||||
) | ||||
Paul Morelle
|
r40994 | plots.append(p) | ||
med_n = scipy.signal.medfilt(ary[1], n + 1) | ||||
Augie Fackler
|
r43346 | p = other_plt.plot( | ||
ary[0], | ||||
med_n, | ||||
color=color[1], | ||||
linewidth=1, | ||||
label='median time last %d' % n, | ||||
) | ||||
Paul Morelle
|
r40994 | plots.append(p) | ||
formatter = mticker.ScalarFormatter() | ||||
formatter.set_scientific(False) | ||||
formatter.set_useOffset(False) | ||||
comb_plt.grid() | ||||
comb_plt.xaxis.set_major_formatter(formatter) | ||||
comb_plt.legend() | ||||
other_plt.grid() | ||||
other_plt.xaxis.set_major_formatter(formatter) | ||||
leg = other_plt.legend() | ||||
leg2plot = {} | ||||
for legline, plot in zip(leg.get_lines(), plots): | ||||
legline.set_picker(5) | ||||
leg2plot[legline] = plot | ||||
def onpick(event): | ||||
legline = event.artist | ||||
plot = leg2plot[legline] | ||||
visible = not plot[0].get_visible() | ||||
for l in plot: | ||||
l.set_visible(visible) | ||||
if visible: | ||||
legline.set_alpha(1.0) | ||||
else: | ||||
legline.set_alpha(0.2) | ||||
fig.canvas.draw() | ||||
Augie Fackler
|
r43346 | |||
Boris Feld
|
r41226 | if title is not None: | ||
fig.canvas.set_window_title(title) | ||||
Paul Morelle
|
r40994 | fig.canvas.mpl_connect('pick_event', onpick) | ||
plt.show() | ||||
if __name__ == '__main__': | ||||
import sys | ||||
if len(sys.argv) > 1: | ||||
print('reading from %r' % sys.argv[1]) | ||||
with open(sys.argv[1], 'r') as fp: | ||||
Boris Feld
|
r41226 | plot(json.load(fp), title=sys.argv[1]) | ||
Paul Morelle
|
r40994 | else: | ||
print('reading from stdin') | ||||
plot(json.load(sys.stdin)) | ||||