Optimization to stop creating new small longs and use the
one previously stored. Issue 2417.
diff --git a/Objects/longobject.c b/Objects/longobject.c
index 6cea51a..ae62cfd 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -13,6 +13,11 @@
 #ifndef NSMALLNEGINTS
 #define NSMALLNEGINTS		5
 #endif
+
+#define MEDIUM_VALUE(x) (Py_SIZE(x) < 0 ? -(x)->ob_digit[0] : \
+			 (Py_SIZE(x) == 0 ? 0 : (x)->ob_digit[0]))
+#define ABS(x) ((x) < 0 ? -(x) : (x))
+
 #if NSMALLNEGINTS + NSMALLPOSINTS > 0
 /* Small integers are preallocated in this array so that they
    can be shared.
@@ -42,11 +47,23 @@
 		return get_small_int(ival); \
 	} while(0)
 
+static PyLongObject * 
+maybe_small_long(PyLongObject *v)
+{
+	if (v && ABS(Py_SIZE(v)) <= 1) {
+		int ival = MEDIUM_VALUE(v);
+		if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
+			Py_DECREF(v);
+			return (PyLongObject *)get_small_int(ival);
+		}
+	}
+	return v;
+}
 #else
 #define CHECK_SMALL_INT(ival)
+#define maybe_small_long(val) (val)
 #endif
 
-#define MEDIUM_VALUE(x) (Py_SIZE(x) < 0 ? -(x)->ob_digit[0] : (Py_SIZE(x) == 0 ? 0 : (x)->ob_digit[0]))
 /* If a freshly-allocated long is already shared, it must
    be a small integer, so negating it must go to PyLong_FromLong */
 #define NEGATE(x) \
@@ -68,8 +85,6 @@
  */
 #define FIVEARY_CUTOFF 8
 
-#define ABS(x) ((x) < 0 ? -(x) : (x))
-
 #undef MIN
 #undef MAX
 #define MAX(x, y) ((x) < (y) ? (y) : (x))
@@ -1982,14 +1997,7 @@
 	if (pend)
 		*pend = str;
 	long_normalize(z);
-	if (ABS(Py_SIZE(z)) <= 1) {
-		long res = MEDIUM_VALUE(z);
-		if (-NSMALLPOSINTS <= res && res <= NSMALLPOSINTS) {
-			Py_DECREF(z);
-			return PyLong_FromLong(res);
-		}
-	}
-	return (PyObject *) z;
+	return (PyObject *) maybe_small_long(z);
 
  onError:
 	Py_XDECREF(z);
@@ -2078,7 +2086,7 @@
 		NEGATE(z);
 	if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0)
 		NEGATE(*prem);
-	*pdiv = z;
+	*pdiv = maybe_small_long(z);
 	return 0;
 }
 
@@ -2335,7 +2343,7 @@
 		while (--i >= 0 && a->ob_digit[i] == b->ob_digit[i])
 			;
 		if (i < 0)
-			return _PyLong_New(0);
+			return (PyLongObject *)PyLong_FromLong(0);
 		if (a->ob_digit[i] < b->ob_digit[i]) {
 			sign = -1;
 			{ PyLongObject *temp = a; a = b; b = temp; }
@@ -2588,7 +2596,7 @@
 	i = a == b ? KARATSUBA_SQUARE_CUTOFF : KARATSUBA_CUTOFF;
 	if (asize <= i) {
 		if (asize == 0)
-			return _PyLong_New(0);
+			return (PyLongObject *)PyLong_FromLong(0);
 		else
 			return x_mul(a, b);
 	}
@@ -3199,7 +3207,7 @@
 	if (x == NULL)
 		return NULL;
 	Py_SIZE(x) = -(Py_SIZE(x));
-	return (PyObject *)x;
+	return (PyObject *)maybe_small_long(x);
 }
 
 static PyObject *
@@ -3264,10 +3272,8 @@
 		}
 		wordshift = shiftby / PyLong_SHIFT;
 		newsize = ABS(Py_SIZE(a)) - wordshift;
-		if (newsize <= 0) {
-			z = _PyLong_New(0);
-			return (PyObject *)z;
-		}
+		if (newsize <= 0)
+		        return PyLong_FromLong(0);
 		loshift = shiftby % PyLong_SHIFT;
 		hishift = PyLong_SHIFT - loshift;
 		lomask = ((digit)1 << hishift) - 1;
@@ -3286,7 +3292,7 @@
 		z = long_normalize(z);
 	}
 rshift_error:
-	return (PyObject *) z;
+	return (PyObject *) maybe_small_long(z);
 
 }
 
@@ -3342,7 +3348,7 @@
 		assert(!accum);
 	z = long_normalize(z);
 lshift_error:
-	return (PyObject *) z;
+	return (PyObject *) maybe_small_long(z);
 }
 
 
@@ -3448,7 +3454,7 @@
 	Py_DECREF(b);
 	z = long_normalize(z);
 	if (negz == 0)
-		return (PyObject *) z;
+		return (PyObject *) maybe_small_long(z);
 	v = long_invert(z);
 	Py_DECREF(z);
 	return v;