[pypy-svn] r58953 - in pypy/build/benchmem: . testing

xoraxax at codespeak.net xoraxax at codespeak.net
Sat Oct 11 11:46:49 CEST 2008


Author: xoraxax
Date: Sat Oct 11 11:46:48 2008
New Revision: 58953

Modified:
   pypy/build/benchmem/runbench.py
   pypy/build/benchmem/smaps.py
   pypy/build/benchmem/testing/test_benchtool.py
Log:
(hpk, xoraxax) Add new basesize benchmark, refactor parsing again.

Modified: pypy/build/benchmem/runbench.py
==============================================================================
--- pypy/build/benchmem/runbench.py	(original)
+++ pypy/build/benchmem/runbench.py	Sat Oct 11 11:46:48 2008
@@ -6,16 +6,55 @@
   and append results to a log file ("bench.log" by default).
 
 """
-import py
 import os, sys, re
+from subprocess import Popen, PIPE
+
+import py
 import smaps
+
 optparse = py.compat.optparse
 mydir = py.magic.autopath().dirpath()
 benchmarkdir = mydir.join("benchmark")
 
+
 class BenchRunner:
     SEPBENCH = "=" * 80
- 
+
+    def log(self, *args):
+        print " ".join(map(str, args))
+
+
+class BenchRunnerBaseSize(BenchRunner):
+    def __init__(self, executable, logpath, options):
+        self.executable = executable
+        self.executable_full_path = py.path.local.sysfind(executable)
+        self.logpath = py.path.local(logpath)
+        self.logstream = self.logpath.open("a")
+        self.options = options
+
+    def write_benchheader(self):
+        print >>self.logstream, self.SEPBENCH 
+        print >>self.logstream, "#benchtype=basesize"
+        print >>self.logstream, "#executable=%s" %(str(self.executable ),)
+        print >>self.logstream
+
+    def run(self):
+        cmds = [str(self.executable_full_path), '-c',  '''import sys; sys.stdout.write("F"); sys.stdout.flush(); raw_input()''']
+        self.log("running %r" % (cmds, ))
+        popen = Popen(cmds, shell=False, stdin=PIPE, stdout=PIPE, close_fds=True)
+        self.write_benchheader()
+        rec = smaps.SmapsRecorder(popen.pid, self.logstream)
+        #print "Reading", popen.pid
+        line = popen.stdout.read(1).strip()
+        assert line == 'F'
+        rec.snapshot()
+        #print "Writing"
+        popen.stdin.write("\n")
+        popen.stdin.flush()
+        #print "Waiting"
+        popen.wait()
+
+
 class BenchRunnerObjsize(BenchRunner):
     def __init__(self, executable, fsname, logpath, options):
         self.executable = executable
@@ -25,9 +64,6 @@
         self.logstream = self.logpath.open("a")
         self.tmpdir = py.path.local.make_numbered_dir(prefix="bench")
         self.options = options
-   
-    def log(self, *args):
-        print " ".join(map(str, args))
 
     def makebench(self, name):
         arglist = str(self.options.numiter)
@@ -131,62 +167,61 @@
 
     def parse(self, logpath):
         f = logpath.open()
-        for result in Result.parse(f):
-            #print "parsed", result
-            self.results.append(result)
+        self.results.extend(self.yield_results(f))
         f.close()
-      
-class Result(object):
-    @classmethod
-    def parseheader(cls, iterline):
+
+    def parseheader(self, stream_iter):
         kw = {}
-        while 1:
-            lineno, line = iterline()
+        for lineno, line in stream_iter:
             if not line.strip():
-                return kw 
+                return kw
             assert line.startswith("#"), line
             key, value = map(str.strip, line[1:].split("="))
             kw[key] = value
 
-    @classmethod
-    def parse(cls, f):
-        def genline():
-            lineno = 1
-            while 1:
-                yield lineno, f.readline()
-                lineno += 1
-        iterline = genline().next
-        lineno, line = iterline()
-        while not f.closed:
-            if not line:
-                break
+    def yield_results(self, stream):
+        stream_iter = enumerate(stream)
+        for lineno, line in stream_iter:
             line = line.rstrip()
             if line != BenchRunner.SEPBENCH:
-                print "ignoring %d: %s" %(lineno, line)
-                lineno, line = iterline()
-                continue
-            kw = cls.parseheader(iterline)
-           
-            benchtype = kw.pop('benchtype')
-            if benchtype == "sizes":
-                snapshots = []
-                lineno, line = iterline()
-                while 1:
-                    mappings = []
-                    while line != smaps.SmapsRecorder.SEPSNAPSHOT:
-                        mappings.append(smaps.Mapping(line))
-                        lineno, line = iterline()
-                        #print "reading", line.strip()
-                    snapshots.append(Snapshot(mappings))
-                    lineno, line = iterline()
-                    #print "reading %d: %s" %(lineno, line)
-                    if not line or line.startswith(BenchRunner.SEPBENCH):
-                        break
-                #print "yielding result", kw['benchname']
-                yield ObjsizeResult(snapshots, **kw)
+                print "ignoring %d: %s" % (lineno, line)
+            else:
+                break
+        while 1:
+            kw = self.parseheader(stream_iter)
+            if kw is None:
+                break
+            yield parse_result(stream_iter, kw)
+
+def parse_result(stream, kw):
+    chosen_cls = None
+    benchtype = kw.pop('benchtype')
+    for scls in Result.__subclasses__():
+        if scls.benchtype == benchtype:
+            chosen_cls = scls
+            break
+    assert chosen_cls is not None, 'Unknown benchtype ' + repr(benchtype)
+    return chosen_cls.parse(stream, kw)
+
+
+class Result(object):
+    @classmethod
+    def parse(cls, lnstream, kw):
+        snapshots = []
+        mappings = []
+        for lineno, line in lnstream:
+            line = line.rstrip()
+            if line == smaps.SmapsRecorder.SEPSNAPSHOT:
+                snapshots.append(Snapshot(mappings))
+                mappings = []
+            elif line == BenchRunner.SEPBENCH:
+                break
             else:
-                assert 0, benchtype
-      
+                mappings.append(smaps.Mapping(line))
+                continue
+        return cls(snapshots, **kw)
+
+
 class ObjsizeResult(Result):
     benchtype = "sizes"
     def __init__(self, snapshots, executable, benchpath, benchname, benchargs):
@@ -210,6 +245,15 @@
                 dirty = mapping.private_dirty + mapping.shared_dirty 
                 assert mapping.rss == dirty + clean
 
+
+class BasesizeResult(Result):
+    benchtype = 'basesize'
+    def __init__(self, snapshots, executable):
+        self.snapshot = snapshots[0]
+        assert len(snapshots) == 1
+        self.executable = executable
+
+
 class Snapshot(object):
     def __init__(self, mappings):
         assert mappings

Modified: pypy/build/benchmem/smaps.py
==============================================================================
--- pypy/build/benchmem/smaps.py	(original)
+++ pypy/build/benchmem/smaps.py	Sat Oct 11 11:46:48 2008
@@ -2,7 +2,7 @@
 import py
 
 class SmapsRecorder:
-    SEPSNAPSHOT = "-"*80 + "\n"
+    SEPSNAPSHOT = "-"*80
 
     def __init__(self, pid, stream):
         self.stream = stream 
@@ -40,7 +40,7 @@
                 headline = nextheadline
         except StopIteration:
             append_attrs(attrs)
-        self.stream.write(self.SEPSNAPSHOT)
+        self.stream.write(self.SEPSNAPSHOT + "\n")
         self.stream.flush()
 
 

Modified: pypy/build/benchmem/testing/test_benchtool.py
==============================================================================
--- pypy/build/benchmem/testing/test_benchtool.py	(original)
+++ pypy/build/benchmem/testing/test_benchtool.py	Sat Oct 11 11:46:48 2008
@@ -158,3 +158,18 @@
         val2 = getattr(snap.mappings[1], name)
         assert sumval == val1 + val2
 
+
+def test_basesize():
+    tmpdir = py.test.ensuretemp("basesize")
+    benchlog = tmpdir.join("log")
+    class Options: pass
+    runner = runbench.BenchRunnerBaseSize("python2.5", benchlog, Options())
+    runner.run()
+    resultset = runbench.ResultSet()
+    resultset.parse(benchlog)
+
+    assert len(resultset.results) == 1
+    result = resultset.results[0]
+    assert result.benchtype == 'basesize'
+    assert result.executable.endswith('python2.5')
+    assert result.snapshot.heap_private() > 42



More information about the Pypy-commit mailing list