[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