#!/usr/bin/env python """ Run: report_graphic [bench_log] """ import os import sys import py import pylab import numpy SPLIT = 10 EXT = ".png" class Plotter(object): def __init__(self, basepath='', show=False): self.basepath = basepath self.show = show def plot_baseint_sizes(self, heap_private, ip_code, ip_data, rest, executables): # XXX add axes scaling heap_private = numpy.array(heap_private) ip_code = numpy.array(ip_code) ip_data = numpy.array(ip_data) rest = numpy.array(rest) pylab.clf() WIDTH = .1 lgt = len(executables) ind = numpy.array([float(i)/lgt for i in range(lgt)]) p0 = pylab.bar(ind, heap_private, WIDTH, color='r') p1 = pylab.bar(ind, ip_code, WIDTH, color='b', bottom=heap_private) p2 = pylab.bar(ind, ip_data, WIDTH, color='w', bottom=heap_private+ip_code) p3 = pylab.bar(ind, rest, WIDTH, color='black', bottom=heap_private+ip_code+ip_data) pylab.xticks(ind + WIDTH/2, executables) pylab.legend([p0[0], p1[0], p2[0], p3[0]], ['heap private', 'ip code', 'ip data', 'rest']) pylab.ylabel('memory consumption (kB)') if self.basepath is not None: pylab.savefig(self.basepath + "base_size" + EXT) if self.show: pylab.show() def plot_objsizes(self, benchresults, names, executables, split=SPLIT): # XXX implement saner colorization colors = ['r', 'g', 'b', 'black', 'white', 'cyan', 'magenta', 'yellow' 'purple', 'grey'] benchresults = numpy.array(benchresults) mapping_file = open(os.path.join(self.basepath, "objsizes_mapping.txt"), "w") end = len(benchresults[0])//split if len(benchresults[0]) % split != 0: end += 1 for i, name in enumerate(names): print >>mapping_file, "B%d: %s" % (i, name) mapping_file.close() for view in range(end): start = view * split end = min((view + 1)*split, len(benchresults[0])) results = benchresults[:, start:end] pylab.clf() lgt = len(results[0]) baseindices = numpy.array([float(i)/lgt for i in range(lgt)]) basewidth = (baseindices[1] - baseindices[0]) skip = (basewidth * .5) / len(benchresults) bars = [] for i, benchresult in enumerate(results): bars.append(pylab.bar(baseindices + skip * i, benchresult, skip, color=colors[i])) pylab.legend([bar[0] for bar in bars], executables) # XXX a lot of magic is required to provide a reasonable # set of non-overlapping xticks pylab.xticks(baseindices + basewidth/4, ['B%d' % i for i in range(start, end)]) pylab.ylabel("memory consumption (kB)") if self.basepath is not None: pylab.savefig(self.basepath + "objsizes_%d%s" % (view, EXT)) if self.show: pylab.show() def plot_appprofiles(self, name2results, base_snapshots): """ This function plots memory consumption of app benchmarks versus time """ SHOW_TS = False SUBTRACT_BASE = False for name, results in name2results: pylab.clf() plots = [] for result in results: timestamps = [float(ss.timestamp) for ss in result.snapshots] min_ts, max_ts = min(timestamps), max(timestamps) d_ts = max_ts - min_ts if SHOW_TS: x = [val - min_ts for val in timestamps] else: x = [(val - min_ts)/d_ts*100 for val in timestamps] if base_snapshots and SUBTRACT_BASE: basesize = base_snapshots[result.executable].heap_and_data(result) else: basesize = 0 # we need a max(\cdot, 0) here because # e.g. the generational GC will likely trigger a nursery # collect that reduces the memory usage compared to the baseline y = [max(snapshot.heap_and_data(result) - basesize, 0) for snapshot in result.snapshots] plots.append(pylab.plot(x, y)) pylab.title(name) pylab.legend(plots, [result.executable_short for result in results]) xlabel = ["wall clock time (%)", "wall clock time (s)"][SHOW_TS] pylab.xlabel(xlabel) ylabel = ["", "incremental "][bool(basesize) and SUBTRACT_BASE] + "heap and dirty static data consumption (kB)" pylab.ylabel(ylabel) if self.basepath is not None: pylab.savefig(self.basepath + 'appprofiles_%s%s' % (name, EXT)) if self.show: pylab.show() def plot_pausehistogram(self, resultset): for name, results in resultset.getname2results(): pylab.clf() pylab.yscale("log") maxsample = 0 range = None for result in results: maxsample = max([maxsample] + result.lst) if maxsample != 0: range = (0, maxsample * 1000) for result in results: samples = [x * 1000 for x in result.lst] legend = "%s-%s" % (result.executable_short, result.benchname) pylab.hist(samples, 10, label=legend, cumulative=False, range=range) pylab.xlabel("Time between two bytecode instruction executions in ms") pylab.ylabel("Executed bytecode instructions") pylab.legend() if self.basepath is not None: pylab.savefig(os.path.join(self.basepath, "pausehistogram_%s%s" % (name, EXT))) if self.show: pylab.show()