Issue #10227: Add an allocation cache for a single slice object.
Patch by Stefan Behnel.
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) 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 @@
 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 @@
 };
 
 
-/* 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 @@
     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 @@
     PyLong_Fini();
     PyFloat_Fini();
     PyDict_Fini();
+    PySlice_Fini();
 
     /* Cleanup Unicode implementation */
     _PyUnicode_Fini();