Skip to content

Commit f34a0cd

Browse files
committed
Issue python#10227: Add an allocation cache for a single slice object.
Patch by Stefan Behnel.
1 parent 2251a3d commit f34a0cd

4 files changed

Lines changed: 34 additions & 7 deletions

File tree

Include/pythonrun.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ PyAPI_FUNC(void) PyByteArray_Fini(void);
211211
PyAPI_FUNC(void) PyFloat_Fini(void);
212212
PyAPI_FUNC(void) PyOS_FiniInterrupts(void);
213213
PyAPI_FUNC(void) _PyGC_Fini(void);
214+
PyAPI_FUNC(void) PySlice_Fini(void);
214215

215216
PyAPI_DATA(PyThreadState *) _Py_Finalizing;
216217
#endif

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1?
1010
Core and Builtins
1111
-----------------
1212

13+
- Issue #10227: Add an allocation cache for a single slice object. Patch by
14+
Stefan Behnel.
15+
1316
- Issue #13393: BufferedReader.read1() now asks the full requested size to
1417
the raw stream instead of limiting itself to the buffer size.
1518

Objects/sliceobject.c

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,19 +80,38 @@ PyObject _Py_EllipsisObject = {
8080
};
8181

8282

83-
/* Slice object implementation
83+
/* Slice object implementation */
8484

85-
start, stop, and step are python objects with None indicating no
85+
/* Using a cache is very effective since typically only a single slice is
86+
* created and then deleted again
87+
*/
88+
static PySliceObject *slice_cache = NULL;
89+
void PySlice_Fini(void)
90+
{
91+
PySliceObject *obj = slice_cache;
92+
if (obj != NULL) {
93+
slice_cache = NULL;
94+
PyObject_Del(obj);
95+
}
96+
}
97+
98+
/* start, stop, and step are python objects with None indicating no
8699
index is present.
87100
*/
88101

89102
PyObject *
90103
PySlice_New(PyObject *start, PyObject *stop, PyObject *step)
91104
{
92-
PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type);
93-
94-
if (obj == NULL)
95-
return NULL;
105+
PySliceObject *obj;
106+
if (slice_cache != NULL) {
107+
obj = slice_cache;
108+
slice_cache = NULL;
109+
_Py_NewReference((PyObject *)obj);
110+
} else {
111+
obj = PyObject_New(PySliceObject, &PySlice_Type);
112+
if (obj == NULL)
113+
return NULL;
114+
}
96115

97116
if (step == NULL) step = Py_None;
98117
Py_INCREF(step);
@@ -260,7 +279,10 @@ slice_dealloc(PySliceObject *r)
260279
Py_DECREF(r->step);
261280
Py_DECREF(r->start);
262281
Py_DECREF(r->stop);
263-
PyObject_Del(r);
282+
if (slice_cache == NULL)
283+
slice_cache = r;
284+
else
285+
PyObject_Del(r);
264286
}
265287

266288
static PyObject *

Python/pythonrun.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,7 @@ Py_Finalize(void)
531531
PyLong_Fini();
532532
PyFloat_Fini();
533533
PyDict_Fini();
534+
PySlice_Fini();
534535

535536
/* Cleanup Unicode implementation */
536537
_PyUnicode_Fini();

0 commit comments

Comments
 (0)