[pypy-svn] r58837 - in pypy/dist/pypy: config interpreter rlib rlib/test translator/goal

xoraxax at codespeak.net xoraxax at codespeak.net
Wed Oct 8 17:14:25 CEST 2008


Author: xoraxax
Date: Wed Oct  8 17:14:23 2008
New Revision: 58837

Added:
   pypy/dist/pypy/rlib/test/test_timer.py
   pypy/dist/pypy/rlib/timer.py
Modified:
   pypy/dist/pypy/config/pypyoption.py
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/interpreter/pycompiler.py
   pypy/dist/pypy/translator/goal/targetpypystandalone.py
Log:
Added trivial timing system that can be used on systems without a profiler. It is disabled by default.

Modified: pypy/dist/pypy/config/pypyoption.py
==============================================================================
--- pypy/dist/pypy/config/pypyoption.py	(original)
+++ pypy/dist/pypy/config/pypyoption.py	Wed Oct  8 17:14:23 2008
@@ -168,6 +168,10 @@
                "make sure that all calls go through space.call_args",
                default=False),
 
+    BoolOption("timing",
+               "timing of various parts of the interpreter (simple profiling)",
+               default=False),
+
     OptionDescription("std", "Standard Object Space Options", [
         BoolOption("withtproxy", "support transparent proxies",
                    default=True),

Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Wed Oct  8 17:14:23 2008
@@ -9,6 +9,7 @@
 from pypy.tool.uid import HUGEVAL_BYTES
 from pypy.rlib.objectmodel import we_are_translated
 from pypy.rlib.debug import make_sure_not_resized
+from pypy.rlib.timer import DummyTimer, Timer
 import os, sys
 
 __all__ = ['ObjSpace', 'OperationError', 'Wrappable', 'W_Root']
@@ -252,6 +253,11 @@
 #        if self.config.objspace.logbytecodes:
 #            self.bytecodecounts = {}
 
+        if self.config.objspace.timing:
+            self.timer = Timer()
+        else:
+            self.timer = DummyTimer()
+
         self.initialize()
 
     def startup(self):
@@ -264,7 +270,10 @@
             modname = self.str_w(w_modname)
             mod = self.interpclass_w(self.getbuiltinmodule(modname))
             if isinstance(mod, Module):
+                import time
+                self.timer.start("startup " + modname)
                 mod.startup(self)
+                self.timer.stop("startup " + modname)
 
     def finish(self):
         w_exitfunc = self.sys.getdictvalue_w(self, 'exitfunc')

Modified: pypy/dist/pypy/interpreter/pycompiler.py
==============================================================================
--- pypy/dist/pypy/interpreter/pycompiler.py	(original)
+++ pypy/dist/pypy/interpreter/pycompiler.py	Wed Oct  8 17:14:23 2008
@@ -242,6 +242,7 @@
 
 ##         flags |= stdlib___future__.generators.compiler_flag   # always on (2.2 compat)
         space = self.space
+        space.timer.start("PythonAST compile")
         try:
             builder = AstBuilder(self.parser, self.grammar_version, space=space)
             for rulename, buildfunc in self.additional_rules.iteritems():
@@ -283,6 +284,7 @@
         except (ValueError, TypeError), e:
             raise OperationError(space.w_SystemError, space.wrap(str(e)))
         assert isinstance(c, PyCode)
+        space.timer.stop("PythonAST compile")
         return c
 
     # interface for pypy.module.recparser

Added: pypy/dist/pypy/rlib/test/test_timer.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/test/test_timer.py	Wed Oct  8 17:14:23 2008
@@ -0,0 +1,20 @@
+from pypy.rlib.timer import Timer
+from pypy.translator.c.test.test_genc import compile
+from pypy.annotation.policy import AnnotatorPolicy
+
+def timer_user():
+    t = Timer()
+    t.start("testa")
+    t.stop("testa")
+    t.start("testb")
+    t.start("testb")
+    t.stop("testb")
+    t.stop("testb")
+    t.dump()
+
+def test_compile_timer():
+    policy = AnnotatorPolicy()
+    policy.allow_someobjects = False
+    f_compiled = compile(timer_user, [], annotatorpolicy=policy)
+    f_compiled(expected_extra_mallocs=0)
+

Added: pypy/dist/pypy/rlib/timer.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rlib/timer.py	Wed Oct  8 17:14:23 2008
@@ -0,0 +1,61 @@
+import time
+import os
+
+
+def _create_name(name, generation):
+    if generation == 0:
+        return name
+    else:
+        return "%s[%s]" % (name, str(generation))
+
+
+class Timer:
+    def __init__(self):
+        self.timings = {}
+        self.levels = {}
+        self.timingorder = []
+
+    def start(self, timer):
+        level = self.levels.setdefault(timer, -1)
+        new_level = level + 1
+        name = _create_name(timer, new_level)
+        if name not in self.timings:
+            self.timingorder.append(name)
+        self.timings[name] = time.time() - self.timings.get(name, 0)
+        self.levels[timer] = new_level
+
+    def stop(self, timer):
+        level = self.levels.setdefault(timer, -1)
+        if level == -1:
+            raise ValueError("Invalid timer name")
+        if level >= 0: # timer is active
+            name = _create_name(timer, level)
+            self.timings[name] = time.time() - self.timings[name]
+            self.levels[timer] = level - 1
+
+    def value(self, timer):
+        level = self.levels.get(timer, -1)
+        if level == -1:
+            result = "%fs" % self.timings[timer]
+        else:
+            result = "%fs (still running)" % (time.time() - self.timings[timer])
+        return result
+
+    def dump(self):
+        outlist = []
+        for timer in self.timingorder:
+            value = self.value(timer)
+            outlist.append("%s = %s" % (timer, value))
+        os.write(2, "\n".join(outlist))
+
+
+class DummyTimer:
+    def start(self, timer):
+        pass
+    def stop(self, timer):
+        pass
+    def value(self, timer):
+        return "Timing disabled"
+    def dump(self):
+        pass
+

Modified: pypy/dist/pypy/translator/goal/targetpypystandalone.py
==============================================================================
--- pypy/dist/pypy/translator/goal/targetpypystandalone.py	(original)
+++ pypy/dist/pypy/translator/goal/targetpypystandalone.py	Wed Oct  8 17:14:23 2008
@@ -31,6 +31,7 @@
     w_os = setup_nanos(space)
 
     def entry_point(argv):
+        space.timer.start("Entrypoint")
         #debug("entry point starting") 
         #for arg in argv: 
         #    debug(" argv -> " + arg)
@@ -45,10 +46,14 @@
             argv = argv[:1] + argv[3:]
         try:
             try:
+                space.timer.start("space.startup")
                 space.call_function(w_run_toplevel, w_call_startup_gateway)
+                space.timer.stop("space.startup")
                 w_executable = space.wrap(argv[0])
                 w_argv = space.newlist([space.wrap(s) for s in argv[1:]])
+                space.timer.start("w_entry_point")
                 w_exitcode = space.call_function(w_entry_point, w_executable, w_argv, w_os)
+                space.timer.stop("w_entry_point")
                 exitcode = space.int_w(w_exitcode)
                 # try to pull it all in
             ##    from pypy.interpreter import main, interactive, error
@@ -61,12 +66,16 @@
                 return 1
         finally:
             try:
+                space.timer.start("space.finish")
                 space.call_function(w_run_toplevel, w_call_finish_gateway)
+                space.timer.stop("space.finish")
             except OperationError, e:
                 debug("OperationError:")
                 debug(" operror-type: " + e.w_type.getname(space, '?'))
                 debug(" operror-value: " + space.str_w(space.str(e.w_value)))
                 return 1
+        space.timer.stop("Entrypoint")
+        space.timer.dump()
         return exitcode
     return entry_point
 



More information about the Pypy-commit mailing list