views:

774

answers:

2

Does someone know of a good reference card for the memory size of python data stucture on 32 and 64 bit platforms ?

If not, this would be nice to have it on SO. The more exhaustive the better ! So how many bytes are used by those python structures (depending on the len and the content type when relevant) ?

 - int
 - float
 - reference
 - str
 - unicode string
 - tuple
 - list
 - dict
 - set
 - array.array
 - numpy.array
 - deque
 - new-style classes object
 - old-style classes object
 - ... and everything I am forgetting !

(for containers that keep only references to other objects, we obviously do not want to count the size of the item themselves, since they may be shared)

Furthermore, is there a way to get the memory used by an object at runtime (recursively or not) ?

+11  A: 

The recommendation from an earlier question on this was to use sys.getsizeof(), quoting:

>>> import sys
>>> x = 2
>>> sys.getsizeof(x)
14
>>> sys.getsizeof(sys.getsizeof)
32
>>> sys.getsizeof('this')
38
>>> sys.getsizeof('this also')
48

You could take this approach:

>>> import sys
>>> import decimal
>>> d = {}
>>> d["int"] = 1
>>> d["float"] = 2.9
>>> d["dict"] = dict()
>>> d["set"] = set()
>>> d["tuple"] = tuple()
>>> d["list"] = list()
>>> d["str"] = "a"
>>> d["unicode"] = u"a"
>>> d["decimal"] = decimal.Decimal(0)
>>> d["object"] = object()
>>> for k in sorted(d):
...     print k, sys.getsizeof(d[k])
...
decimal 40
dict 140
float 16
int 12
list 36
object 8
set 116
str 25
tuple 28
unicode 28
hughdbrown
Thanks, and sorry for the dupe for the second question... too bad I am using 2.5 and not 2.6...
LeMiz
I forgot I had a virtual box with a recent ubuntu on it! That's strange, sys.getsizeof(dict) is 136 for me (python 2.6 running on a kubuntu vm, hosted by OS X, so I am not sure of anything)
LeMiz
@LeMiz: For me (Python 2.6, Windows XP SP3), sys.getsizeof(dict) -> 436; sys.getsizeof(dict()) -> 140
John Machin
LeMiz-Kubuntu:python2.6Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41)[GCC 4.3.3] on linux2Type "help", "copyright", "credits" or "license" for more information.>>> import sys>>> sys.getsizeof(dict)436>>> sys.getsizeof(dict())136
LeMiz
shouldn't the values be `0`, `0.0`, `''` and `u''` for consistency?
SilentGhost
Unfortunately, this does not work for NumPy arrays (they return 44 bytes whatever their size, with version 1.5).
EOL
+1  A: 

I've been happily using pympler for such tasks. It's compatible with many versions of Python -- the asizeof module in particular goes back to 2.2!

For example, using hughdbrown's example but with from pympler import asizeof at the start and print asizeof.asizeof(v) at the end, I see (system Python 2.5 on MacOSX 10.5):

$ python pymp.py 
set 120
unicode 32
tuple 32
int 16
decimal 152
float 16
list 40
object 0
dict 144
str 32

Clearly there is some approximation here, but I've found it very useful for footprint analysis and tuning.

Alex Martelli
Some curiosities: most of you numbers are 4 higher; object is 0; and decimal is about 4 times larger by your estimate.
hughdbrown
Yep. The "4 higher" actually mostly look like "rounding up to a multiple of 8" which I believe is correct for the way malloc behaves here. No idea why decimal gets so distorted (with pympler on 2.6, too).
Alex Martelli
Actually, you should use pympler.asizeof.flatsize() to get a similar functionality to sys.getsizeof(). There is also an align= parameter you can use (which is 8 by default as Alex pointed out).
Pankrat