summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-05-02 20:19:34 (GMT)
committerTim Peters <tim.peters@gmail.com>2002-05-02 20:19:34 (GMT)
commit4ce71f77c35bafe058196bb9607cb0b1051542d9 (patch)
treeabda95ac501ff57eccaa5973502168719babb7ce
parentedbffc17254cc4f5d441fd9bc1311d4ede81e8da (diff)
downloadcpython-4ce71f77c35bafe058196bb9607cb0b1051542d9.zip
cpython-4ce71f77c35bafe058196bb9607cb0b1051542d9.tar.gz
cpython-4ce71f77c35bafe058196bb9607cb0b1051542d9.tar.bz2
PyObject_Realloc(): If a small block is shrinking, bite the expense of
copying it if at least 25% of the input block can be reclaimed.
-rw-r--r--Objects/obmalloc.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index a21f303..14f9e25 100644
--- a/Objects/obmalloc.c
+++ b/Objects/obmalloc.c
@@ -793,11 +793,22 @@ PyObject_Realloc(void *p, size_t nbytes)
if (ADDRESS_IN_RANGE(p, pool->arenaindex)) {
/* We're in charge of this block */
size = INDEX2SIZE(pool->szidx);
- if (size >= nbytes)
- /* Don't bother if a smaller size was requested. */
- return p;
- /* We need more memory. */
- assert(nbytes != 0);
+ if (nbytes <= size) {
+ /* The block is staying the same or shrinking. If
+ * it's shrinking, there's a tradeoff: it costs
+ * cycles to copy the block to a smaller size class,
+ * but it wastes memory not to copy it. The
+ * compromise here is to copy on shrink only if at
+ * least 25% of size can be shaved off.
+ */
+ if (4 * nbytes > 3 * size) {
+ /* It's the same,
+ * or shrinking and new/old > 3/4.
+ */
+ return p;
+ }
+ size = nbytes;
+ }
bp = PyObject_Malloc(nbytes);
if (bp != NULL) {
memcpy(bp, p, size);