We can improve performance of cpython by using stealing methods (_PyList_AppendTakeRef, _PyDict_SetItem_Take2, PyTuple_FromPairSteal etc.) instead of the normal ones. Using stealing methods we typically avoid an incref/decref pair and sometimes error handling is simplified. We should only make changes where it makes a performance impact, the code is not more complex and the modules or methods affected are performance critical.
A list of possible cases (there might be more).
Location
Module / context
Helper
Modules/_csv.c:688
csv reader, per field
_PyList_AppendTakeRef
Modules/pyexpat.c:472
pyexpat StartElement, per attribute
_PyDict_SetItem_Take2
Modules/_elementtree.c:3351
ElementTree C accel attrib dict
_PyDict_SetItem_Take2
Modules/_io/bytesio.c:577
io.BytesIO.readlines
_PyList_AppendTakeRef
Modules/_io/iobase.c:756
io.IOBase.readlines (generic)
_PyList_AppendTakeRef
Objects/frameobject.c:639 & 658
frame f_locals / vars() / tracing
_PyList_AppendTakeRef
Modules/_pickle.c:5138
pickle Pickler memo copy
_PyDict_SetItem_Take2
Modules/_io/textio.c:2337 & 2343
io.TextIOWrapper readline (multi-chunk)
_PyList_AppendTakeRef
Modules/_asynciomodule.c:1213
asyncio future done-callback compaction
_PyList_AppendTakeRef
Update: Most cases already have an open PR, for new ones please open a separate issue.
Hi, I found an additional candidate in Python/modsupport.c::do_mkdict(), where Py_BuildValue() dictionary construction passes newly owned key/value references to PyDict_SetItem() and then immediately decrefs them. Using _PyDict_SetItem_Take2() avoids those INCREF/DECREF round trips. Targeted Py_BuildValue() dict microbenchmarks showed small but repeatable ~1–5% improvements across the tested cases.
Activity
pythongh-150942: Set issue number on the re speedup news entry
pythongh-150942: Speed up json.loads array and object decoding
omkar-334 commented on Jun 5, 2026
hi @eendebakpt @StanFromIreland can i work on a module , maybe csv or textio
eendebakpt commented on Jun 5, 2026
Sure! Try out, benchmark, test. If benchmarks show significant improvements you can open a PR, if not just report here briefly.
Merge branch 'main' into pythongh-150942-csv-appendtakeref
omkar-334 commented on Jun 6, 2026
hi @eendebakpt , i've opned a PR for csv reader, since that has 1.08x speedup, matches your PR speedups....
however, the benchmarks for io.BytesIO.readlines show that there is not a significant improvements
do you think i should still make a pr for this
Merge branch 'main' into pythongh-150942-csv-appendtakeref
tangyuan0821 commented on Jun 7, 2026
Happy to try _asynciomodule.c — swap PyList_Append for
_PyList_AppendTakeRef in future_add_done_callback.
I'll benchmark first.
gh-150942: Speed up frame local item collection (gh-151002)
gh-150942: Speed up re.findall and re.sub/subn result building (gh-15…
pythongh-150942: Speed up asyncio future add_done_callback
25 remaining items
tkim602 commented on Aug 21, 2026
Hi, I found an additional candidate in Python/modsupport.c::do_mkdict(), where Py_BuildValue() dictionary construction passes newly owned key/value references to PyDict_SetItem() and then immediately decrefs them. Using _PyDict_SetItem_Take2() avoids those INCREF/DECREF round trips. Targeted Py_BuildValue() dict microbenchmarks showed small but repeatable ~1–5% improvements across the tested cases.
Opened #156199 for this.
eendebakpt commented on Aug 22, 2026
It seems all of the obvious cases have an open PR, so I am going to close the issue. For any new cases, please open a new issue.
StanFromIreland commented on Aug 22, 2026
I think we should keep this issue open however, unless you plan to move all the PRs?
gh-150942: Speed up BytesIO.readlines() using reference-stealing appe…
picnixz commented on Oct 2, 2026
Keeping it open because there are still PRs.
Merge upstream main and preserve FrameLocalsProxy.values() ownership