https://github.com/python/cpython/commit/3bd7730bbda3e38db5920a7b8c95958ca90342bf
commit: 3bd7730bbda3e38db5920a7b8c95958ca90342bf
branch: main
author: Pieter Eendebak <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2024-12-26T15:17:22Z
summary:

gh-126868: Add freelist for compact ints to `_PyLong_New` (#128181)

Co-authored-by: Kumar Aditya <[email protected]>

files:
A 
Misc/NEWS.d/next/Core_and_Builtins/2024-12-22-15-47-44.gh-issue-126868.RpjKez.rst
M Objects/longobject.c

diff --git 
a/Misc/NEWS.d/next/Core_and_Builtins/2024-12-22-15-47-44.gh-issue-126868.RpjKez.rst
 
b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-22-15-47-44.gh-issue-126868.RpjKez.rst
new file mode 100644
index 00000000000000..ede383deb4ad31
--- /dev/null
+++ 
b/Misc/NEWS.d/next/Core_and_Builtins/2024-12-22-15-47-44.gh-issue-126868.RpjKez.rst
@@ -0,0 +1 @@
+Increase usage of freelist for :class:`int` allocation.
diff --git a/Objects/longobject.c b/Objects/longobject.c
index bd7ff68d0899c6..d449a01cedf886 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -156,7 +156,7 @@ PyLongObject *
 _PyLong_New(Py_ssize_t size)
 {
     assert(size >= 0);
-    PyLongObject *result;
+    PyLongObject *result = NULL;
     if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
         PyErr_SetString(PyExc_OverflowError,
                         "too many digits in integer");
@@ -165,19 +165,25 @@ _PyLong_New(Py_ssize_t size)
     /* Fast operations for single digit integers (including zero)
      * assume that there is always at least one digit present. */
     Py_ssize_t ndigits = size ? size : 1;
-    /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
-       sizeof(digit)*size.  Previous incarnations of this code used
-       sizeof() instead of the offsetof, but this risks being
-       incorrect in the presence of padding between the header
-       and the digits. */
-    result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) +
-                             ndigits*sizeof(digit));
-    if (!result) {
-        PyErr_NoMemory();
-        return NULL;
+
+    if (ndigits == 1) {
+        result = (PyLongObject *)_Py_FREELIST_POP(PyLongObject, ints);
+    }
+    if (result == NULL) {
+        /* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
+        sizeof(digit)*size.  Previous incarnations of this code used
+        sizeof() instead of the offsetof, but this risks being
+        incorrect in the presence of padding between the header
+        and the digits. */
+        result = PyObject_Malloc(offsetof(PyLongObject, long_value.ob_digit) +
+                                ndigits*sizeof(digit));
+        if (!result) {
+            PyErr_NoMemory();
+            return NULL;
+        }
+        _PyObject_Init((PyObject*)result, &PyLong_Type);
     }
     _PyLong_SetSignAndDigitCount(result, size != 0, size);
-    _PyObject_Init((PyObject*)result, &PyLong_Type);
     /* The digit has to be initialized explicitly to avoid
      * use-of-uninitialized-value. */
     result->long_value.ob_digit[0] = 0;

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to