On Tue, 2009-02-17 at 17:04 +0100, Christian Heimes wrote:
> Tim Wintle wrote:
> > Basically malloc() and free() are computationally expensive, so Python
> > tries to call them as little as possible - but it's quite clever at
> > knowing what to do - e.g. if a list has already grown large then python
> > assumes it might grow large again and keeps hold of a percentage of the
> > memory.
> 
> You are almost right. Python's mutable container types like have a
> non-linear growth rate.
> 
> >From the file listobject.c
> 
> /*
> This over-allocates proportional to the list size, making room
> for additional growth.  The over-allocation is mild, but is
> enough to give linear-time amortized behavior over a long
> sequence of appends() in the presence of a poorly-performing
> system realloc().
> The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
> */
> 
> new_allocated = (newsize >> 3) + (newsize < 9 ? 3 : 6);

Sorry, I think I didn't phrase myself very well - I was trying to
explain that de-allocation of memory follows different scaling behaviour
to allocation - so a large list that's shrunk is likely to take more
memory than a small list that's grown i.e. the part just above your
quote:


/* 
Bypass realloc() when a previous overallocation is large enough
to accommodate the newsize.  If the newsize falls lower than half
the allocated size, then proceed with the realloc() to shrink the list.
*/
if (allocated >= newsize && newsize >= (allocated >> 1)) {
        assert(self->ob_item != NULL || newsize == 0);
        Py_SIZE(self) = newsize;
        return 0;
}


it's all very clever stuff btw.


--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to