]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-37207: Use PEP 590 vectorcall to speed up tuple() (GH-18936)
authorDong-hee Na <donghee.na92@gmail.com>
Fri, 13 Mar 2020 13:57:00 +0000 (22:57 +0900)
committerGitHub <noreply@github.com>
Fri, 13 Mar 2020 13:57:00 +0000 (14:57 +0100)
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

Misc/NEWS.d/next/Core and Builtins/2020-03-12-02-41-12.bpo-37207.ye7OM3.rst [new file with mode: 0644]
Objects/tupleobject.c

diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-03-12-02-41-12.bpo-37207.ye7OM3.rst b/Misc/NEWS.d/next/Core and Builtins/2020-03-12-02-41-12.bpo-37207.ye7OM3.rst
new file mode 100644 (file)
index 0000000..ecbadf9
--- /dev/null
@@ -0,0 +1,2 @@
+Speed up calls to ``tuple()`` by using the :pep:`590` ``vectorcall`` calling
+convention. Patch by Dong-hee Na.
index 52ecb5446fe8fcd6587d62502e5365f9204d2d17..14ab53fca22705976639f364d9cfe6ebb9d8a04d 100644 (file)
@@ -705,6 +705,26 @@ tuple_new_impl(PyTypeObject *type, PyObject *iterable)
         return PySequence_Tuple(iterable);
 }
 
+static PyObject *
+tuple_vectorcall(PyObject *type, PyObject * const*args,
+                 size_t nargsf, PyObject *kwnames)
+{
+    if (kwnames && PyTuple_GET_SIZE(kwnames) != 0) {
+        PyErr_Format(PyExc_TypeError, "tuple() takes no keyword arguments");
+        return NULL;
+    }
+    Py_ssize_t nargs = PyVectorcall_NARGS(nargsf);
+    if (nargs > 1) {
+        PyErr_Format(PyExc_TypeError, "tuple() expected at most 1 argument, got %zd", nargs);
+        return NULL;
+    }
+
+    if (nargs) {
+        return tuple_new_impl((PyTypeObject *)type, args[0]);
+    }
+    return PyTuple_New(0);
+}
+
 static PyObject *
 tuple_subtype_new(PyTypeObject *type, PyObject *iterable)
 {
@@ -863,6 +883,7 @@ PyTypeObject PyTuple_Type = {
     0,                                          /* tp_alloc */
     tuple_new,                                  /* tp_new */
     PyObject_GC_Del,                            /* tp_free */
+    .tp_vectorcall = tuple_vectorcall,
 };
 
 /* The following function breaks the notion that tuples are immutable: