Skip to content

Commit ea2ef1c

Browse files
committed
bpo-43575: Use PEP 590 vectorcall to speed up map()
1 parent 7cb033c commit ea2ef1c

File tree

2 files changed

+45
-2
lines changed

2 files changed

+45
-2
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Speed up calls to ``map()`` by using the :pep:`590` ``vectorcall`` calling
2+
convention. Patch by Dong-hee Na.

Python/bltinmodule.c

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1264,8 +1264,48 @@ map_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
12641264
}
12651265
lz->iters = iters;
12661266
func = PyTuple_GET_ITEM(args, 0);
1267-
Py_INCREF(func);
1268-
lz->func = func;
1267+
lz->func = Py_NewRef(func);
1268+
1269+
return (PyObject *)lz;
1270+
}
1271+
1272+
static PyObject *
1273+
map_vectorcall(PyObject *type, PyObject * const*args,
1274+
size_t nargsf, PyObject *kwnames)
1275+
{
1276+
PyTypeObject *tp = (PyTypeObject *)type;
1277+
if (tp == &PyMap_Type && !_PyArg_NoKwnames("map", kwnames)) {
1278+
return NULL;
1279+
}
1280+
1281+
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
1282+
if (nargs < 2) {
1283+
PyErr_SetString(PyExc_TypeError,
1284+
"map() must have at least two arguments.");
1285+
return NULL;
1286+
}
1287+
1288+
PyObject *iters = PyTuple_New(nargs-1);
1289+
if (iters == NULL) {
1290+
return NULL;
1291+
}
1292+
1293+
for (int i=1; i<nargs; i++) {
1294+
PyObject *it = PyObject_GetIter(args[i]);
1295+
if (it == NULL) {
1296+
Py_DECREF(iters);
1297+
return NULL;
1298+
}
1299+
PyTuple_SET_ITEM(iters, i-1, it);
1300+
}
1301+
1302+
mapobject *lz = (mapobject *)tp->tp_alloc(tp, 0);
1303+
if (lz == NULL) {
1304+
Py_DECREF(iters);
1305+
return NULL;
1306+
}
1307+
lz->iters = iters;
1308+
lz->func = Py_NewRef(args[0]);
12691309

12701310
return (PyObject *)lz;
12711311
}
@@ -1403,6 +1443,7 @@ PyTypeObject PyMap_Type = {
14031443
PyType_GenericAlloc, /* tp_alloc */
14041444
map_new, /* tp_new */
14051445
PyObject_GC_Del, /* tp_free */
1446+
.tp_vectorcall = (vectorcallfunc)map_vectorcall
14061447
};
14071448

14081449

0 commit comments

Comments
 (0)