[Python-checkins] cpython: Optimize call to Python function without argument

victor.stinner python-checkins at python.org
Mon Aug 22 06:37:25 EDT 2016


https://hg.python.org/cpython/rev/7dd85b19c873
changeset:   102835:7dd85b19c873
user:        Victor Stinner <victor.stinner at gmail.com>
date:        Mon Aug 22 12:29:42 2016 +0200
summary:
  Optimize call to Python function without argument

Issue #27128. When a Python function is called with no arguments, but all
parameters have a default value: use default values as arguments for the fast
path.

files:
  Python/ceval.c |  42 ++++++++++++++++++++++++++++---------
  1 files changed, 31 insertions(+), 11 deletions(-)


diff --git a/Python/ceval.c b/Python/ceval.c
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -4801,8 +4801,8 @@
 */
 
 static PyObject*
-_PyFunction_FastCallNoKw(PyObject **args, Py_ssize_t na,
-                         PyCodeObject *co, PyObject *globals)
+_PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na,
+                         PyObject *globals)
 {
     PyFrameObject *f;
     PyThreadState *tstate = PyThreadState_GET();
@@ -4837,8 +4837,10 @@
     return result;
 }
 
+/* Similar to _PyFunction_FastCall() but keywords are passed a (key, value)
+   pairs in stack */
 static PyObject *
-fast_function(PyObject *func, PyObject **stack, int n, int na, int nk)
+fast_function(PyObject *func, PyObject **stack, int n, int nargs, int nk)
 {
     PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
     PyObject *globals = PyFunction_GET_GLOBALS(func);
@@ -4850,11 +4852,20 @@
     PCALL(PCALL_FUNCTION);
     PCALL(PCALL_FAST_FUNCTION);
 
-    if (argdefs == NULL && co->co_argcount == na &&
-        co->co_kwonlyargcount == 0 && nk == 0 &&
+    if (co->co_kwonlyargcount == 0 && nk == 0 &&
         co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
     {
-        return _PyFunction_FastCallNoKw(stack, na, co, globals);
+        if (argdefs == NULL && co->co_argcount == nargs) {
+            return _PyFunction_FastCallNoKw(co, stack, nargs, globals);
+        }
+        else if (nargs == 0 && argdefs != NULL
+                 && co->co_argcount == Py_SIZE(argdefs)) {
+            /* function called with no arguments, but all parameters have
+               a default value: use default values as arguments .*/
+            stack = &PyTuple_GET_ITEM(argdefs, 0);
+            return _PyFunction_FastCallNoKw(co, stack, Py_SIZE(argdefs),
+                                            globals);
+        }
     }
 
     kwdefs = PyFunction_GET_KW_DEFAULTS(func);
@@ -4871,8 +4882,8 @@
         nd = 0;
     }
     return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
-                                    stack, na,
-                                    stack + na, nk,
+                                    stack, nargs,
+                                    stack + nargs, nk,
                                     d, nd, kwdefs,
                                     closure, name, qualname);
 }
@@ -4893,11 +4904,20 @@
     /* issue #27128: support for keywords will come later */
     assert(kwargs == NULL);
 
-    if (argdefs == NULL && co->co_argcount == nargs &&
-        co->co_kwonlyargcount == 0 &&
+    if (co->co_kwonlyargcount == 0 && kwargs == NULL &&
         co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
     {
-        return _PyFunction_FastCallNoKw(args, nargs, co, globals);
+        if (argdefs == NULL && co->co_argcount == nargs) {
+            return _PyFunction_FastCallNoKw(co, args, nargs, globals);
+        }
+        else if (nargs == 0 && argdefs != NULL
+                 && co->co_argcount == Py_SIZE(argdefs)) {
+            /* function called with no arguments, but all parameters have
+               a default value: use default values as arguments .*/
+            args = &PyTuple_GET_ITEM(argdefs, 0);
+            return _PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs),
+                                            globals);
+        }
     }
 
     kwdefs = PyFunction_GET_KW_DEFAULTS(func);

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list