]> granicus.if.org Git - python/commitdiff
Issue #28839: Optimize function_call()
authorVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Jan 2017 00:58:17 +0000 (01:58 +0100)
committerVictor Stinner <victor.stinner@gmail.com>
Tue, 3 Jan 2017 00:58:17 +0000 (01:58 +0100)
function_call() now simply calls _PyFunction_FastCallDict().

_PyFunction_FastCallDict() is more efficient: it contains fast paths for the
common case (optimized code object and no keyword argument).

Objects/funcobject.c

index 63aa9de5834c9be7329d7a4dc972a7778b1e6105..a3af4b372a183108611a5c27c448e4fd72a4eb84 100644 (file)
@@ -563,55 +563,14 @@ func_traverse(PyFunctionObject *f, visitproc visit, void *arg)
 }
 
 static PyObject *
-function_call(PyObject *func, PyObject *arg, PyObject *kw)
+function_call(PyObject *func, PyObject *args, PyObject *kwargs)
 {
-    PyObject *result;
-    PyObject *argdefs;
-    PyObject *kwtuple = NULL;
-    PyObject **d, **k;
-    Py_ssize_t nk, nd;
-
-    argdefs = PyFunction_GET_DEFAULTS(func);
-    if (argdefs != NULL && PyTuple_Check(argdefs)) {
-        d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0);
-        nd = PyTuple_GET_SIZE(argdefs);
-    }
-    else {
-        d = NULL;
-        nd = 0;
-    }
-
-    if (kw != NULL && PyDict_Check(kw)) {
-        Py_ssize_t pos, i;
-        nk = PyDict_GET_SIZE(kw);
-        kwtuple = PyTuple_New(2*nk);
-        if (kwtuple == NULL)
-            return NULL;
-        k = &PyTuple_GET_ITEM(kwtuple, 0);
-        pos = i = 0;
-        while (PyDict_Next(kw, &pos, &k[i], &k[i+1])) {
-            Py_INCREF(k[i]);
-            Py_INCREF(k[i+1]);
-            i += 2;
-        }
-        nk = i/2;
-    }
-    else {
-        k = NULL;
-        nk = 0;
-    }
-
-    result = PyEval_EvalCodeEx(
-        PyFunction_GET_CODE(func),
-        PyFunction_GET_GLOBALS(func), (PyObject *)NULL,
-        &PyTuple_GET_ITEM(arg, 0), PyTuple_GET_SIZE(arg),
-        k, nk, d, nd,
-        PyFunction_GET_KW_DEFAULTS(func),
-        PyFunction_GET_CLOSURE(func));
-
-    Py_XDECREF(kwtuple);
+    PyObject **stack;
+    Py_ssize_t nargs;
 
-    return result;
+    stack = &PyTuple_GET_ITEM(args, 0);
+    nargs = PyTuple_GET_SIZE(args);
+    return _PyFunction_FastCallDict(func, stack, nargs, kwargs);
 }
 
 /* Bind a function to an object */