Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reserve memory for list in Python?

When programming in Python, is it possible to reserve memory for a list that will be populated with a known number of items, so that the list will not be reallocated several times while building it? I've looked through the docs for a Python list type, and have not found anything that seems to do this. However, this type of list building shows up in a few hotspots of my code, so I want to make it as efficient as possible.

Edit: Also, does it even make sense to do something like this in a language like Python? I'm a fairly experienced programmer, but new to Python and still getting a feel for its way of doing things. Does Python internally allocate all objects in separate heap spaces, defeating the purpose of trying to minimize allocations, or are primitives like ints, floats, etc. stored directly in lists?

like image 955
dsimcha Avatar asked Feb 11 '09 14:02

dsimcha


People also ask

How does Python allocate memory for a list?

Whenever additional elements are added to the list, Python dynamically allocates extra memory to accommodate future elements without resizing the container. This implies, adding a single element to an empty list will incite Python to allocate more memory than 8 bytes.

How is memory allocated list?

A free list is a data structure used in a scheme for dynamic memory allocation. It operates by connecting unallocated regions of memory together in a linked list, using the first word of each unallocated region as a pointer to the next.

What is the capacity of a list in Python?

Maximum length of a list is platform dependent and depends upon address space and/or RAM. The maxsize constant defined in sys module returns 263-1 on 64 bit system. The largest positive integer supported by the platform's Py_ssize_t type, is the maximum size lists, strings, dicts, and many other containers can have.


2 Answers

Here's four variants:

  • an incremental list creation
  • "pre-allocated" list
  • array.array()
  • numpy.zeros()

 

python -mtimeit -s"N=10**6" "a = []; app = a.append;"\     "for i in xrange(N):  app(i);" 10 loops, best of 3: 390 msec per loop  python -mtimeit -s"N=10**6" "a = [None]*N; app = a.append;"\     "for i in xrange(N):  a[i] = i" 10 loops, best of 3: 245 msec per loop  python -mtimeit -s"from array import array; N=10**6" "a = array('i', [0]*N)"\     "for i in xrange(N):" "  a[i] = i" 10 loops, best of 3: 541 msec per loop  python -mtimeit -s"from numpy import zeros; N=10**6" "a = zeros(N,dtype='i')"\     "for i in xrange(N):" "  a[i] = i" 10 loops, best of 3: 353 msec per loop 

It shows that [None]*N is the fastest and array.array is the slowest in this case.

like image 64
jfs Avatar answered Sep 22 '22 19:09

jfs


you can create list of the known length like this:

>>> [None] * known_number 
like image 28
SilentGhost Avatar answered Sep 24 '22 19:09

SilentGhost