]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-92914: Round the allocated size for lists up to the even number (GH-92915)
authorSerhiy Storchaka <storchaka@gmail.com>
Thu, 19 May 2022 05:43:50 +0000 (08:43 +0300)
committerGitHub <noreply@github.com>
Thu, 19 May 2022 05:43:50 +0000 (08:43 +0300)
Lib/test/test_sys.py
Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst [new file with mode: 0644]
Objects/listobject.c

index 9c0f4a69289d2e80cf25152ef325f1e4bf002605..94a09ff549331a2e8158c17d290c687da70996ca 100644 (file)
@@ -1432,9 +1432,10 @@ class SizeofTest(unittest.TestCase):
         import re
         check(re.finditer('',''), size('2P'))
         # list
-        samples = [[], [1,2,3], ['1', '2', '3']]
-        for sample in samples:
-            check(list(sample), vsize('Pn') + len(sample)*self.P)
+        check(list([]), vsize('Pn'))
+        check(list([1]), vsize('Pn') + 2*self.P)
+        check(list([1, 2]), vsize('Pn') + 2*self.P)
+        check(list([1, 2, 3]), vsize('Pn') + 4*self.P)
         # sortwrapper (list)
         # XXX
         # cmpwrapper (list)
diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst b/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst
new file mode 100644 (file)
index 0000000..1242a15
--- /dev/null
@@ -0,0 +1 @@
+Always round the allocated size for lists up to the nearest even number.
index b50623ed73d94005ca0e12edadfcb6f012ba703e..0a99ec919b8c871a103a1c452f645c91fe2a2d6e 100644 (file)
@@ -94,6 +94,12 @@ list_preallocate_exact(PyListObject *self, Py_ssize_t size)
     assert(self->ob_item == NULL);
     assert(size > 0);
 
+    /* Since the Python memory allocator has granularity of 16 bytes on 64-bit
+     * platforms (8 on 32-bit), there is no benefit of allocating space for
+     * the odd number of items, and there is no drawback of rounding the
+     * allocated size up to the nearest even number.
+     */
+    size = (size + 1) & ~(size_t)1;
     PyObject **items = PyMem_New(PyObject*, size);
     if (items == NULL) {
         PyErr_NoMemory();