in tools/dev/benchmarks/suite1/benchmark.py [0:0]
def cmdline_chart_compare(db, options, *args):
import matplotlib
matplotlib.use('Agg')
import numpy as np
import matplotlib.pylab as plt
labels = []
timing_sets = []
command_names = None
run_kinds = parse_timings_selections(db, *args)
# iterate the timings selections and accumulate data
for run_kind in run_kinds:
query = TimingQuery(db, run_kind)
timings = query.get_timings()
if not timings:
print("No timings for %s" % run_kind.label())
continue
labels.append(run_kind.label())
timing_sets.append(timings)
# it only makes sense to compare those commands that have timings
# in the first selection, because that is the one everything else
# is compared to. Remember the first selection's command names.
if not command_names:
command_names = query.get_sorted_command_names()
if len(timing_sets) < 2:
bail("Not enough timings")
if options.command_names:
command_names = [name for name in command_names
if name in options.command_names]
chart_path = options.chart_path
if not chart_path:
chart_path = 'compare_' + '_'.join(
[ filesystem_safe_string(l) for l in labels ]
) + '.svg'
N = len(command_names)
M = len(timing_sets) - 1
if M < 2:
M = 2
group_positions = np.arange(N) # the y locations for the groups
dist = 1. / (1. + M)
height = (1. - dist) / M # the height of the bars
fig = plt.figure(figsize=(12, 5 + 0.2*N*M))
plot1 = fig.add_subplot(121)
plot2 = fig.add_subplot(122)
left = timing_sets[0]
# Iterate timing sets. Each loop produces one bar for each command name
# group.
for label_i,label in enumerate(labels[1:],1):
right = timing_sets[label_i]
if not right:
continue
for cmd_i, command_name in enumerate(command_names):
if command_name not in right:
#skip
continue
left_N, left_min, left_max, left_avg = left[command_name]
right_N, right_min, right_max, right_avg = right[command_name]
div_avg = 100. * (do_div(left_avg, right_avg) - 1.0)
if div_avg <= 0:
col = '#55dd55'
else:
col = '#dd5555'
diff_val = do_diff(left_avg, right_avg)
ofs = (dist + height) / 2. + height * (label_i - 1)
barheight = height * (1.0 - dist)
y = float(cmd_i) + ofs
plot1.barh((y, ),
(div_avg, ),
barheight,
color=col, edgecolor='white')
plot1.text(0., y + height/2.,
'%s %+5.1f%%' % (label, div_avg),
ha='right', va='center', size='small',
rotation=0, family='monospace')
plot2.barh((y, ),
(diff_val, ),
barheight,
color=col, edgecolor='white')
plot2.text(0., y + height/2.,
'%s %+6.2fs' % (label, diff_val),
ha='right', va='center', size='small',
rotation=0, family='monospace')
for p in (plot1, plot2):
xlim = list(p.get_xlim())
if xlim[1] < 10.:
xlim[1] = 10.
# make sure the zero line is far enough right so that the annotations
# fit inside the chart. About half the width should suffice.
if xlim[0] > -xlim[1]:
xlim[0] = -xlim[1]
p.set_xlim(*xlim)
p.set_xticks((0,))
p.set_yticks(group_positions + (height / 2.))
p.set_yticklabels(())
p.set_ylim((len(command_names), 0))
p.grid()
plot1.set_xticklabels(('+-0%',), rotation=0)
plot1.set_title('Average runtime change from %s in %%' % labels[0],
size='medium')
plot2.set_xticklabels(('+-0s',), rotation=0)
plot2.set_title('Average runtime change from %s in seconds' % labels[0],
size='medium')
margin = 1./(2 + N*M)
titlemargin = 0
if options.title:
titlemargin = margin * 1.5
fig.subplots_adjust(left=0.005, right=0.995, wspace=0.3, bottom=margin,
top=1.0-margin-titlemargin)
ystep = (1.0 - 2.*margin - titlemargin) / len(command_names)
for idx,command_name in enumerate(command_names):
ylabel = '%s\nvs. %.1fs' % (
command_name,
left[command_name][3])
ypos=1.0 - margin - titlemargin - ystep/M - ystep * idx
plt.figtext(0.5, ypos,
command_name,
ha='center', va='top',
size='medium', weight='bold')
plt.figtext(0.5, ypos - ystep/(M+1),
'%s\n= %.2fs' % (
labels[0], left[command_name][3]),
ha='center', va='top',
size='small')
if options.title:
plt.figtext(0.5, 1. - titlemargin/2, options.title, ha='center',
va='center', weight='bold')
plt.savefig(chart_path)
print('wrote chart file:', chart_path)