bpo-38373: Change list overallocating strategy. (GH-18952) · python/cpython@2fe815e

@@ -54,15 +54,17 @@ list_resize(PyListObject *self, Py_ssize_t newsize)

5454

* enough to give linear-time amortized behavior over a long

5555

* sequence of appends() in the presence of a poorly-performing

5656

* system realloc().

57-

* The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...

57+

* Add padding to make the allocated size multiple of 4.

58+

* The growth pattern is: 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, ...

5859

* Note: new_allocated won't overflow because the largest possible value

5960

* is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.

6061

*/

61-

new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6);

62-

if (new_allocated > (size_t)PY_SSIZE_T_MAX / sizeof(PyObject *)) {

63-

PyErr_NoMemory();

64-

return -1;

65-

}

62+

new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3;

63+

/* Do not overallocate if the new size is closer to overalocated size

64+

* than to the old size.

65+

*/

66+

if (newsize - Py_SIZE(self) > (Py_ssize_t)(new_allocated - newsize))

67+

new_allocated = ((size_t)newsize + 3) & ~(size_t)3;

66686769

if (newsize == 0)

6870

new_allocated = 0;