Skip to content

Commit 9ee88cd

Browse files
authored
bpo-37207: Use PEP 590 vectorcall to speed up tuple() (GH-18936)
Master: ./python.exe -m pyperf timeit "tuple((1, 2, 3, 4, 5))" Mean +- std dev: 361 ns +- 15 ns PEP-590: ./python.exe -m pyperf timeit "tuple((1, 2, 3, 4, 5))" Mean +- std dev: 203 ns +- 13 ns
1 parent 3f2f4fe commit 9ee88cd

File tree

2 files changed

+23
-0
lines changed

2 files changed

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

Objects/tupleobject.c

+21
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,26 @@ tuple_new_impl(PyTypeObject *type, PyObject *iterable)
705705
return PySequence_Tuple(iterable);
706706
}
707707

708+
static PyObject *
709+
tuple_vectorcall(PyObject *type, PyObject * const*args,
710+
size_t nargsf, PyObject *kwnames)
711+
{
712+
if (kwnames && PyTuple_GET_SIZE(kwnames) != 0) {
713+
PyErr_Format(PyExc_TypeError, "tuple() takes no keyword arguments");
714+
return NULL;
715+
}
716+
Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
717+
if (nargs > 1) {
718+
PyErr_Format(PyExc_TypeError, "tuple() expected at most 1 argument, got %zd", nargs);
719+
return NULL;
720+
}
721+
722+
if (nargs) {
723+
return tuple_new_impl((PyTypeObject *)type, args[0]);
724+
}
725+
return PyTuple_New(0);
726+
}
727+
708728
static PyObject *
709729
tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
710730
{
@@ -863,6 +883,7 @@ PyTypeObject PyTuple_Type = {
863883
0, /* tp_alloc */
864884
tuple_new, /* tp_new */
865885
PyObject_GC_Del, /* tp_free */
886+
.tp_vectorcall = tuple_vectorcall,
866887
};
867888

868889
/* The following function breaks the notion that tuples are immutable:

0 commit comments

Comments
 (0)