Skip to content

Commit 6ee879f

Browse files
authored
gh-138325: steal list items in INTRINSIC_LIST_TO_TUPLE opcode (#149960)
1 parent acefff9 commit 6ee879f

2 files changed

Lines changed: 11 additions & 2 deletions

File tree

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Speed up converting a list to a tuple in the ``tuple(genexpr)`` fast path
2+
and in starred tuple displays (e.g. ``(*a, *b)``) by stealing the list's
3+
items into the tuple instead of copying them.

Python/intrinsics.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
#include "pycore_genobject.h" // _PyAsyncGenValueWrapperNew
88
#include "pycore_interpframe.h" // _PyFrame_GetLocals()
99
#include "pycore_intrinsics.h" // INTRINSIC_PRINT
10+
#include "pycore_list.h" // _PyList_AsTupleAndClear()
11+
#include "pycore_object.h" // _PyObject_IsUniquelyReferenced()
1012
#include "pycore_pyerrors.h" // _PyErr_SetString()
1113
#include "pycore_runtime.h" // _Py_ID()
1214
#include "pycore_typevarobject.h" // _Py_make_typevar()
@@ -190,8 +192,12 @@ unary_pos(PyThreadState* unused, PyObject *value)
190192
static PyObject *
191193
list_to_tuple(PyThreadState* unused, PyObject *v)
192194
{
193-
assert(PyList_Check(v));
194-
return PyTuple_FromArray(((PyListObject *)v)->ob_item, Py_SIZE(v));
195+
/* INTRINSIC_LIST_TO_TUPLE is only emitted by the compiler for a
196+
freshly-built, uniquely-referenced temporary list, so steal its items
197+
into the tuple instead of copying them. */
198+
assert(PyList_CheckExact(v));
199+
assert(_PyObject_IsUniquelyReferenced(v));
200+
return _PyList_AsTupleAndClear((PyListObject *)v);
195201
}
196202

197203
static PyObject *

0 commit comments

Comments
 (0)