From 9a2ed09a314c44f96aab5cf9c7fc0a5e7b194aca Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 May 2022 08:32:43 +0300 Subject: [PATCH 1/5] gh-92914: Always round up the size allocated for lists up to 16 bytes --- .../2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst | 1 + Objects/listobject.c | 10 ++++++++++ 2 files changed, 11 insertions(+) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst 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 index 00000000000000..5217a15f844d0a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst @@ -0,0 +1 @@ +Always round up the size allocated for lists up to 16 bytes. diff --git a/Objects/listobject.c b/Objects/listobject.c index b50623ed73d940..aa6a875a51e4ff 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -94,6 +94,16 @@ 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, + * there is no benefit of allocating space for the odd number of items, + * and there is no drawback of rounding it up. + */ + if (sizeof(PyObject*) > 4) { + size = (size + 1) & ~(size_t)1; + } + else { + size = (size + 3) & ~(size_t)3; + } PyObject **items = PyMem_New(PyObject*, size); if (items == NULL) { PyErr_NoMemory(); From a6b1a798e67795a001bff775f8c71b7d9d5f98a1 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 May 2022 09:12:25 +0300 Subject: [PATCH 2/5] Round up to the even number. --- Objects/listobject.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Objects/listobject.c b/Objects/listobject.c index aa6a875a51e4ff..0a99ec919b8c87 100644 --- a/Objects/listobject.c +++ b/Objects/listobject.c @@ -94,16 +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, - * there is no benefit of allocating space for the odd number of items, - * and there is no drawback of rounding it up. + /* 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. */ - if (sizeof(PyObject*) > 4) { - size = (size + 1) & ~(size_t)1; - } - else { - size = (size + 3) & ~(size_t)3; - } + size = (size + 1) & ~(size_t)1; PyObject **items = PyMem_New(PyObject*, size); if (items == NULL) { PyErr_NoMemory(); From 8599f813161c66abd9c19dd1ea404d1bdba24982 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 May 2022 09:57:46 +0300 Subject: [PATCH 3/5] Fix tests. --- Lib/test/test_sys.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index 9c0f4a69289d2e..94a09ff549331a 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -1432,9 +1432,10 @@ def get_gen(): yield 1 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) From 67779ed557aaedaf8a7d7a81bcc2816a8f66b39e Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 May 2022 11:03:07 +0300 Subject: [PATCH 4/5] Update 2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst --- .../2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 5217a15f844d0a..1645305ebe5d5e 100644 --- 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 @@ -1 +1 @@ -Always round up the size allocated for lists up to 16 bytes. +Always round up the allocated size for lists to the nearest even number. From 7025f22a25350b14035889008071168a34237980 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Wed, 18 May 2022 11:06:03 +0300 Subject: [PATCH 5/5] Update 2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst --- .../2022-05-18-08-32-33.gh-issue-92914.tJUeTD.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 index 1645305ebe5d5e..1242a15c029dc1 100644 --- 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 @@ -1 +1 @@ -Always round up the allocated size for lists to the nearest even number. +Always round the allocated size for lists up to the nearest even number.