Skip to content

Commit f180a59

Browse files
committed
Add freelists for list and tuple iterators
1 parent 8abd6ce commit f180a59

File tree

4 files changed

+21
-12
lines changed

4 files changed

+21
-12
lines changed

Include/internal/pycore_freelist_state.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ extern "C" {
1111
# define PyTuple_MAXSAVESIZE 20 // Largest tuple to save on freelist
1212
# define Py_tuple_MAXFREELIST 2000 // Maximum number of tuples of each size to save
1313
# define Py_lists_MAXFREELIST 80
14+
# define Py_list_iters_MAXFREELIST 10
15+
# define Py_tuple_iters_MAXFREELIST 10
1416
# define Py_dicts_MAXFREELIST 80
1517
# define Py_dictkeys_MAXFREELIST 80
1618
# define Py_floats_MAXFREELIST 100
@@ -39,6 +41,8 @@ struct _Py_freelists {
3941
struct _Py_freelist ints;
4042
struct _Py_freelist tuples[PyTuple_MAXSAVESIZE];
4143
struct _Py_freelist lists;
44+
struct _Py_freelist list_iters;
45+
struct _Py_freelist tuple_iters;
4246
struct _Py_freelist dicts;
4347
struct _Py_freelist dictkeys;
4448
struct _Py_freelist slices;

Objects/listobject.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3906,15 +3906,17 @@ PyTypeObject PyListIter_Type = {
39063906
static PyObject *
39073907
list_iter(PyObject *seq)
39083908
{
3909-
_PyListIterObject *it;
3910-
39113909
if (!PyList_Check(seq)) {
39123910
PyErr_BadInternalCall();
39133911
return NULL;
39143912
}
3915-
it = PyObject_GC_New(_PyListIterObject, &PyListIter_Type);
3916-
if (it == NULL)
3917-
return NULL;
3913+
_PyListIterObject *it = _Py_FREELIST_POP(_PyListIterObject, list_iters);
3914+
if (it == NULL) {
3915+
it = PyObject_GC_New(_PyListIterObject, &PyListIter_Type);
3916+
if (it == NULL) {
3917+
return NULL;
3918+
}
3919+
}
39183920
it->it_index = 0;
39193921
it->it_seq = (PyListObject *)Py_NewRef(seq);
39203922
_PyObject_GC_TRACK(it);
@@ -3927,7 +3929,7 @@ listiter_dealloc(PyObject *self)
39273929
_PyListIterObject *it = (_PyListIterObject *)self;
39283930
_PyObject_GC_UNTRACK(it);
39293931
Py_XDECREF(it->it_seq);
3930-
PyObject_GC_Del(it);
3932+
_Py_FREELIST_FREE(list_iters, it, PyObject_GC_Del);
39313933
}
39323934

39333935
static int

Objects/object.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -923,6 +923,8 @@ _PyObject_ClearFreeLists(struct _Py_freelists *freelists, int is_finalization)
923923
clear_freelist(&freelists->tuples[i], is_finalization, free_object);
924924
}
925925
clear_freelist(&freelists->lists, is_finalization, free_object);
926+
clear_freelist(&freelists->list_iters, is_finalization, free_object);
927+
clear_freelist(&freelists->tuple_iters, is_finalization, free_object);
926928
clear_freelist(&freelists->dicts, is_finalization, free_object);
927929
clear_freelist(&freelists->dictkeys, is_finalization, PyMem_Free);
928930
clear_freelist(&freelists->slices, is_finalization, free_object);

Objects/tupleobject.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -994,7 +994,7 @@ tupleiter_dealloc(_PyTupleIterObject *it)
994994
{
995995
_PyObject_GC_UNTRACK(it);
996996
Py_XDECREF(it->it_seq);
997-
PyObject_GC_Del(it);
997+
_Py_FREELIST_FREE(tuple_iters, it, PyObject_GC_Del);
998998
}
999999

10001000
static int
@@ -1116,15 +1116,16 @@ PyTypeObject PyTupleIter_Type = {
11161116
static PyObject *
11171117
tuple_iter(PyObject *seq)
11181118
{
1119-
_PyTupleIterObject *it;
1120-
11211119
if (!PyTuple_Check(seq)) {
11221120
PyErr_BadInternalCall();
11231121
return NULL;
11241122
}
1125-
it = PyObject_GC_New(_PyTupleIterObject, &PyTupleIter_Type);
1126-
if (it == NULL)
1127-
return NULL;
1123+
_PyTupleIterObject *it = _Py_FREELIST_POP(_PyTupleIterObject, tuple_iters);
1124+
if (it == NULL) {
1125+
it = PyObject_GC_New(_PyTupleIterObject, &PyTupleIter_Type);
1126+
if (it == NULL)
1127+
return NULL;
1128+
}
11281129
it->it_index = 0;
11291130
it->it_seq = (PyTupleObject *)Py_NewRef(seq);
11301131
_PyObject_GC_TRACK(it);

0 commit comments

Comments
 (0)