summaryrefslogtreecommitdiff
path: root/Objects/obmalloc.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2002-05-02 20:19:34 +0000
committerTim Peters <tim.peters@gmail.com>2002-05-02 20:19:34 +0000
commitcf2d6e6f218b42bd4491e3d9e8bddfa636da44af (patch)
tree9e03984a7a601efc7c3f4ae1c9cd7f8a378a4ccb /Objects/obmalloc.c
parentdf4af78dfcfb0eff570f09794bcdef08af449621 (diff)
downloadcpython-cf2d6e6f218b42bd4491e3d9e8bddfa636da44af.tar.gz
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.
Diffstat (limited to 'Objects/obmalloc.c')
-rw-r--r--Objects/obmalloc.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/Objects/obmalloc.c b/Objects/obmalloc.c
index a21f3037d7..14f9e2574a 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);