From f34a0cdc6cbf6507508392e4588a9ca0ce8cb6b0 Mon Sep 17 00:00:00 2001 From: Antoine Pitrou Date: Fri, 18 Nov 2011 20:14:34 +0100 Subject: Issue #10227: Add an allocation cache for a single slice object. Patch by Stefan Behnel. --- Include/pythonrun.h | 1 + Misc/NEWS | 3 +++ Objects/sliceobject.c | 36 +++++++++++++++++++++++++++++------- Python/pythonrun.c | 1 + 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/Include/pythonrun.h b/Include/pythonrun.h index bdad15c..fc6c854 100644 --- a/Include/pythonrun.h +++ b/Include/pythonrun.h @@ -211,6 +211,7 @@ PyAPI_FUNC(void) PyByteArray_Fini(void); PyAPI_FUNC(void) PyFloat_Fini(void); PyAPI_FUNC(void) PyOS_FiniInterrupts(void); PyAPI_FUNC(void) _PyGC_Fini(void); +PyAPI_FUNC(void) PySlice_Fini(void); PyAPI_DATA(PyThreadState *) _Py_Finalizing; #endif diff --git a/Misc/NEWS b/Misc/NEWS index 0a1c67b..183e4ed 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 3.3 Alpha 1? Core and Builtins ----------------- +- Issue #10227: Add an allocation cache for a single slice object. Patch by + Stefan Behnel. + - Issue #13393: BufferedReader.read1() now asks the full requested size to the raw stream instead of limiting itself to the buffer size. diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index 2f5c045..c4a1907 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -80,19 +80,38 @@ PyObject _Py_EllipsisObject = { }; -/* Slice object implementation +/* Slice object implementation */ - start, stop, and step are python objects with None indicating no +/* Using a cache is very effective since typically only a single slice is + * created and then deleted again + */ +static PySliceObject *slice_cache = NULL; +void PySlice_Fini(void) +{ + PySliceObject *obj = slice_cache; + if (obj != NULL) { + slice_cache = NULL; + PyObject_Del(obj); + } +} + +/* start, stop, and step are python objects with None indicating no index is present. */ PyObject * PySlice_New(PyObject *start, PyObject *stop, PyObject *step) { - PySliceObject *obj = PyObject_New(PySliceObject, &PySlice_Type); - - if (obj == NULL) - return NULL; + PySliceObject *obj; + if (slice_cache != NULL) { + obj = slice_cache; + slice_cache = NULL; + _Py_NewReference((PyObject *)obj); + } else { + obj = PyObject_New(PySliceObject, &PySlice_Type); + if (obj == NULL) + return NULL; + } if (step == NULL) step = Py_None; Py_INCREF(step); @@ -260,7 +279,10 @@ slice_dealloc(PySliceObject *r) Py_DECREF(r->step); Py_DECREF(r->start); Py_DECREF(r->stop); - PyObject_Del(r); + if (slice_cache == NULL) + slice_cache = r; + else + PyObject_Del(r); } static PyObject * diff --git a/Python/pythonrun.c b/Python/pythonrun.c index 0f2f050..0c267fc 100644 --- a/Python/pythonrun.c +++ b/Python/pythonrun.c @@ -531,6 +531,7 @@ Py_Finalize(void) PyLong_Fini(); PyFloat_Fini(); PyDict_Fini(); + PySlice_Fini(); /* Cleanup Unicode implementation */ _PyUnicode_Fini(); -- cgit v0.12