[pypy-svn] r59606 - in pypy/build/benchmem: . testing
fijal at codespeak.net
fijal at codespeak.net
Fri Oct 31 20:19:18 CET 2008
Author: fijal
Date: Fri Oct 31 20:19:17 2008
New Revision: 59606
Added:
pypy/build/benchmem/testing/conftest.py (contents, props changed)
pypy/build/benchmem/testing/test_report_graph.py (contents, props changed)
Modified:
pypy/build/benchmem/report_graphic.py
Log:
A bit of progress - now report_graphic is nicely tested
Modified: pypy/build/benchmem/report_graphic.py
==============================================================================
--- pypy/build/benchmem/report_graphic.py (original)
+++ pypy/build/benchmem/report_graphic.py Fri Oct 31 20:19:17 2008
@@ -10,10 +10,101 @@
HEAP = runbench.Mappings.HEAP
CODE = runbench.Mappings.CODE
DATA = runbench.Mappings.DATA
-BASE = ''
-SHOW = False
+SPLIT = 10
-def process_baseint_sizes(results):
+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, results):
+ # 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(results)
+ 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, [result.executable for result in results])
+ 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.ps")
+ if self.show:
+ pylab.show()
+ res = {}
+ for i, value in enumerate(ip_code + ip_data + heap_private + rest):
+ res[results[i].executable] = value
+ return res
+
+ 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)
+ names = numpy.array(names)
+ end = len(benchresults[0])//split
+ if len(benchresults[0]) % split != 0:
+ end += 1
+
+ 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.ps" % view)
+ if self.show:
+ pylab.show()
+
+ def plot_appprofiles(self, name2results, totals):
+ """ This function plots incremental memory consumption of app benchmarks
+ (withou interpreter size) versus time (in %s)
+ """
+
+ for name, results in name2results:
+ pylab.clf()
+ plots = []
+ for result in results:
+ lgt = len(result.snapshots)
+ x = [(float(i)/lgt)*100 for i in range(lgt)]
+ y = [snapshot.private - totals[result.executable]
+ for snapshot in result.snapshots]
+ pylab.title(name)
+ plots.append(pylab.plot(x, y))
+
+ pylab.legend(plots, [result.executable for result in results])
+ pylab.xlabel("time (%)")
+ pylab.ylabel("incremental private memory consumption (kB)")
+ if self.basepath is not None:
+ pylab.savefig(BASE + 'appprofiles_%s.ps' % name)
+ if self.show:
+ pylab.show()
+
+def process_baseint_sizes(results, plotter):
""" This function plots base interpreter sizes of various interpreters
with bars specifying:
@@ -35,31 +126,9 @@
inv=True).
filter(group=HEAP, inv=True).private for result in
results])
- return plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results)
-
-def plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results):
- # XXX add axes scaling
- pylab.clf()
- WIDTH = .1
- lgt = len(results)
- 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, [result.executable for result in results])
- pylab.legend([p0[0], p1[0], p2[0], p3[0]],
- ['heap private', 'ip code', 'ip data', 'rest'])
- pylab.savefig(BASE + "base_size.ps")
- if SHOW:
- pylab.show()
- res = {}
- for i, value in enumerate(ip_code + ip_data + heap_private + rest):
- res[results[i].executable] = value
- return res
+ return plotter.plot_baseint_sizes(heap_private, ip_code, ip_data, rest, results)
-def process_objsizes(resultset):
+def process_objsizes(resultset, plotter):
""" This function creates series of graphs for showing incremental
private memory consumed for object allocation (without base interpreter
size)
@@ -76,72 +145,19 @@
for _, results in results:
for i, result in enumerate(results):
benchresults[i].append(incremental_private(result))
- plot_objsizes(benchresults, names, executables)
+ plotter.plot_objsizes(benchresults, names, executables)
-def plot_objsizes(benchresults, names, executables):
- # XXX implement saner colorization
- colors = ['r', 'g', 'b', 'black', 'white', 'cyan', 'magenta', 'yellow'
- 'purple', 'grey']
-
- benchresults = numpy.array(benchresults)
- names = numpy.array(names)
-
- split = 10 # max number of bars per graph
- for view in range(len(benchresults[0])/split):
- 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.savefig(BASE + "objsizes_%d.ps" % view)
- if SHOW:
- pylab.show()
-
-def process_appprofiles(resultset, totals):
- """ This function plots incremental memory consumption of app benchmarks
- (withou interpreter size) versus time (in %s)
- """
-
- pylab.clf()
- for name, results in resultset.filter(benchtype="appprofiles").getname2results():
- plots = []
- for result in results:
- lgt = len(result.snapshots)
- x = [(float(i)/lgt)*100 for i in range(lgt)]
- y = [snapshot.private - totals[result.executable]
- for snapshot in result.snapshots]
- pylab.title(name)
- plots.append(pylab.plot(x, y))
-
- pylab.legend(plots, [result.executable for result in results])
- pylab.xlabel("time (%)")
- pylab.ylabel("incremental private memory consumption")
- pylab.savefig(BASE + 'appprofiles_%s.ps' % name)
- if SHOW:
- pylab.show()
-
def main(filename):
+ plotter = Plotter()
resultset = runbench.ResultSet()
resultset.parse(py.path.local(filename))
totals = process_baseint_sizes(resultset.filter(benchtype="basesize").
- results)
- process_objsizes(resultset.filter(benchtype="objsizes"))
- process_appprofiles(resultset.filter(benchtype="appprofiles"),
- totals)
+ results, plotter)
+ process_objsizes(resultset.filter(benchtype="objsizes"), plotter)
+ plotter.plot_appprofiles(resultset.filter(benchtype="appprofiles"),
+ totals)
if __name__ == '__main__':
if len(sys.argv) > 3:
Added: pypy/build/benchmem/testing/conftest.py
==============================================================================
--- (empty file)
+++ pypy/build/benchmem/testing/conftest.py Fri Oct 31 20:19:17 2008
@@ -0,0 +1,8 @@
+
+import py
+
+Option = py.test.config.Option
+option = py.test.config.addoptions("dotviewer options",
+ Option('--view', action="store_true", dest="view", default=False,
+ help="allow interactive tests"),
+ )
Added: pypy/build/benchmem/testing/test_report_graph.py
==============================================================================
--- (empty file)
+++ pypy/build/benchmem/testing/test_report_graph.py Fri Oct 31 20:19:17 2008
@@ -0,0 +1,42 @@
+
+import py, os
+from report_graphic import Plotter
+
+class MockResult(object):
+ def __init__(self, executable, snapshots=[]):
+ self.executable = executable
+ self.snapshots = snapshots
+
+class MockSnapshot(object):
+ def __init__(self, private):
+ self.private = private
+
+class TestPlotter(object):
+ def setup_class(cls):
+ if py.test.config.option.view:
+ cls.plotter = Plotter(None, True)
+ else:
+ tmpdir = py.test.ensuretemp('plotter')
+ cls.plotter = Plotter(str(tmpdir) + os.path.sep)
+ cls.results = [MockResult('py1'), MockResult('py2')]
+
+ def test_baseint_sizes(self):
+ # this should show two equal bars, with different colors inside
+ self.plotter.plot_baseint_sizes([1, 0], [1, 1], [1, 2], [1, 1],
+ self.results)
+
+ def test_objsizes(self):
+ bars = [[1, 2, 3, 4, 5, 6], [2, 4, 6, 8, 10, 12]]
+ names = ['B%d' for i in range(6)]
+ # this should show two graphs full of bars, where one is 2x other
+ self.plotter.plot_objsizes(bars, names, ['py1', 'py2'], 4)
+
+ def test_appprofiles(self):
+ def new_snapshots(*lst):
+ return [MockSnapshot(i) for i in lst]
+
+ results = [MockResult('py1', new_snapshots(1, 2, 3, 4, 5, 6, 7)),
+ MockResult('py2', new_snapshots(7, 6, 5, 4, 3, 2, 1))]
+ name2results = [('bench1', results), ('bench2', results)]
+ # this one should show two identical graphs of shape of X
+ self.plotter.plot_appprofiles(name2results, {'py1': 1, 'py2': 0})
More information about the Pypy-commit
mailing list