[pypy-svn] r5337 - in pypy/trunk/src/pypy: interpreter objspace

arigo at codespeak.net arigo at codespeak.net
Sat Jun 26 01:04:59 CEST 2004


Author: arigo
Date: Sat Jun 26 01:04:51 2004
New Revision: 5337

Modified:
   pypy/trunk/src/pypy/interpreter/argument.py
   pypy/trunk/src/pypy/interpreter/gateway.py
   pypy/trunk/src/pypy/objspace/descroperation.py
Log:
Huge performance improvement (30-50%) by special-casing calls to built-in
functions early.  Not entierely satisfying, but the special-case is well
marked as such and everything also works fine if it is disabled.


Modified: pypy/trunk/src/pypy/interpreter/argument.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/argument.py	(original)
+++ pypy/trunk/src/pypy/interpreter/argument.py	Sat Jun 26 01:04:51 2004
@@ -17,8 +17,6 @@
     blind_arguments = 0
 
     def __init__(self, space, args_w=[], kwds_w={}):
-        assert isinstance(args_w, list)  # I keep forgetting the 'space'
-        assert isinstance(kwds_w, dict)  # argument so hopefully this helps
         self.space = space
         self.args_w = args_w
         self.kwds_w = kwds_w

Modified: pypy/trunk/src/pypy/interpreter/gateway.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/gateway.py	(original)
+++ pypy/trunk/src/pypy/interpreter/gateway.py	Sat Jun 26 01:04:51 2004
@@ -86,6 +86,44 @@
     def getdocstring(self):
         return self.docstring
 
+    def performance_shortcut_call(self, space, args):
+        # this shortcut is only used for performance reasons
+        if self.generalargs or args.kwds_w:
+            return None
+        args_w = args.args_w
+        if self.ismethod:
+            if not args_w:
+                return None
+            args_w = list(args_w)
+            args_w[0] = space.unwrap(args_w[0])
+        if self.spacearg:
+            w_result = self.func(space, *args_w)
+        else:
+            w_result = self.func(*args_w)
+        if w_result is None:
+            w_result = space.w_None
+        return w_result
+
+    def performance_shortcut_call_meth(self, space, w_obj, args):
+        # this shortcut is only used for performance reasons
+        if self.generalargs:
+            if self.ismethod and not self.spacearg and len(self.sig[0]) == 1:
+                w_result = self.func(space.unwrap(w_obj), args)
+            else:
+                return None
+        else:
+            if args.kwds_w:
+                return None
+            if self.ismethod:
+                w_obj = space.unwrap(w_obj) # abuse name w_obj
+            if self.spacearg:
+                w_result = self.func(space, w_obj, *args.args_w)
+            else:
+                w_result = self.func(w_obj, *args.args_w)
+        if w_result is None:
+            w_result = space.w_None
+        return w_result
+
 
 class BuiltinFrame(eval.Frame):
     "Frame emulation for BuiltinCode."

Modified: pypy/trunk/src/pypy/objspace/descroperation.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/descroperation.py	(original)
+++ pypy/trunk/src/pypy/objspace/descroperation.py	Sat Jun 26 01:04:51 2004
@@ -2,6 +2,7 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter.baseobjspace import ObjSpace
 from pypy.interpreter.function import Function
+from pypy.interpreter.gateway import BuiltinCode
 from pypy.interpreter.argument import Arguments
 
 class Object:
@@ -61,8 +62,14 @@
 
     def get_and_call_args(space, w_descr, w_obj, args):
         descr = space.unwrap_builtin(w_descr)
-        if isinstance(descr, Function):
+        if type(descr) is Function:
             # special-case Functions to avoid infinite recursion
+            if isinstance(descr.code, BuiltinCode):
+                # this sub-special case is ONLY for performance reasons
+                w_result = descr.code.performance_shortcut_call_meth(space,
+                                                                     w_obj, args)
+                if w_result is not None:
+                    return w_result
             return descr.call_args(args.prepend(w_obj))
         else:
             w_impl = space.get(w_descr, w_obj)
@@ -84,6 +91,11 @@
 ##        return space.get_and_call(w_descr, w_obj, w_args, w_kwargs)
 
     def call_args(space, w_obj, args):
+        if type(w_obj) is Function and isinstance(w_obj.code, BuiltinCode):
+            # this special case is ONLY for performance reasons
+            w_result = w_obj.code.performance_shortcut_call(space, args)
+            if w_result is not None:
+                return w_result
         w_descr = space.lookup(w_obj, '__call__')
         if w_descr is None:
             raise OperationError(space.w_TypeError, 



More information about the Pypy-commit mailing list