[Python-checkins] bpo-43575: Use PEP 590 vectorcall to speed up map() (GH-24955)

corona10 webhook-mailer at python.org
Mon Mar 22 06:01:28 EDT 2021


https://github.com/python/cpython/commit/86883d40e93acae980e52b90fddd7d042e439beb
commit: 86883d40e93acae980e52b90fddd7d042e439beb
branch: master
author: Dong-hee Na <donghee.na at python.org>
committer: corona10 <donghee.na92 at gmail.com>
date: 2021-03-22T19:01:14+09:00
summary:

bpo-43575: Use PEP 590 vectorcall to speed up map() (GH-24955)

files:
A Misc/NEWS.d/next/Core and Builtins/2021-03-21-12-26-32.bpo-43575.pl-nSg.rst
M Python/bltinmodule.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2021-03-21-12-26-32.bpo-43575.pl-nSg.rst b/Misc/NEWS.d/next/Core and Builtins/2021-03-21-12-26-32.bpo-43575.pl-nSg.rst
new file mode 100644
index 0000000000000..102325830347a
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2021-03-21-12-26-32.bpo-43575.pl-nSg.rst	
@@ -0,0 +1,2 @@
+Speed up calls to ``map()`` by using the :pep:`590` ``vectorcall`` calling
+convention. Patch by Dong-hee Na.
diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c
index 4683103e09437..9f83c036d0929 100644
--- a/Python/bltinmodule.c
+++ b/Python/bltinmodule.c
@@ -1264,8 +1264,48 @@ map_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
     }
     lz->iters = iters;
     func = PyTuple_GET_ITEM(args, 0);
-    Py_INCREF(func);
-    lz->func = func;
+    lz->func = Py_NewRef(func);
+
+    return (PyObject *)lz;
+}
+
+static PyObject *
+map_vectorcall(PyObject *type, PyObject * const*args,
+                size_t nargsf, PyObject *kwnames)
+{
+    PyTypeObject *tp = (PyTypeObject *)type;
+    if (tp == &PyMap_Type && !_PyArg_NoKwnames("map", kwnames)) {
+        return NULL;
+    }
+
+    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+    if (nargs < 2) {
+        PyErr_SetString(PyExc_TypeError,
+           "map() must have at least two arguments.");
+        return NULL;
+    }
+
+    PyObject *iters = PyTuple_New(nargs-1);
+    if (iters == NULL) {
+        return NULL;
+    }
+
+    for (int i=1; i<nargs; i++) {
+        PyObject *it = PyObject_GetIter(args[i]);
+        if (it == NULL) {
+            Py_DECREF(iters);
+            return NULL;
+        }
+        PyTuple_SET_ITEM(iters, i-1, it);
+    }
+
+    mapobject *lz = (mapobject *)tp->tp_alloc(tp, 0);
+    if (lz == NULL) {
+        Py_DECREF(iters);
+        return NULL;
+    }
+    lz->iters = iters;
+    lz->func = Py_NewRef(args[0]);
 
     return (PyObject *)lz;
 }
@@ -1403,6 +1443,7 @@ PyTypeObject PyMap_Type = {
     PyType_GenericAlloc,                /* tp_alloc */
     map_new,                            /* tp_new */
     PyObject_GC_Del,                    /* tp_free */
+    .tp_vectorcall = (vectorcallfunc)map_vectorcall
 };
 
 



More information about the Python-checkins mailing list