<div class="gmail_quote">On 26 September 2012 00:35, Tim Chase <span dir="ltr"><<a href="mailto:python.list@tim.thechases.com" target="_blank">python.list@tim.thechases.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div class="im">On 09/25/12 17:55, Oscar Benjamin wrote:<br>
> On 25 September 2012 23:10, Tim Chase <<a href="mailto:python.list@tim.thechases.com">python.list@tim.thechases.com</a>> wrote:<br>
</div><div class="im">>> If tuples provide a savings but you find them opaque, you might also<br>
>> consider named-tuples for clarity.<br>
><br>
> Do they have the same memory usage?<br>
><br>
> Since tuples don't have a per-instance __dict__, I'd expect them to be a<br>
> lot lighter. I'm not sure if I'm interpreting the results below properly<br>
> but they seem to suggest that a namedtuple can have a memory consumption<br>
> several times larger than an ordinary tuple.<br>
<br>
</div>I think the "how much memory is $METHOD using" topic of the thread<br>
is the root of the problem. From my testing of your question:<br>
<br>
>>> import collections, sys<br>
<div class="im">>>> A = collections.namedtuple('A', ['x', 'y'])<br>
</div>>>> nt = A(1,3)<br>
>>> t = (1,3)<br>
>>> sys.getsizeof(nt)<br>
72<br>
>>> sys.getsizeof(t)<br>
72<br>
>>> nt_s = set(dir(nt))<br>
>>> t_s = set(dir(t))<br>
>>> t_s ^ nt_s<br>
set(['__module__', '_make', '_asdict', '_replace', '_fields',<br>
'__slots__', 'y', 'x'])<br>
>>> t_s - nt_s<br>
set([])<br></blockquote><div><br></div><div>On my system these is an additional __dict__ attribute and it is bigger than the original tuple:</div><div><div>$ python</div><div>Python 2.7.3 (default, Apr 20 2012, 22:39:59) </div>
<div>[GCC 4.6.3] on linux2</div><div>Type "help", "copyright", "credits" or "license" for more information.</div><div>>>> import collections, sys</div><div>>>> A = collections.namedtuple('A', ['x', 'y'])</div>
<div>>>> nt = A(1,3)</div><div>>>> t = (1,3)</div><div>>>> set(dir(nt)) - set(dir(t))</div><div>set(['__module__', '_replace', '_make', 'y', '__slots__', '_asdict', '__dict__', 'x', '_fields'])</div>
<div>>>> sys.getsizeof(nt.__dict__)</div><div>280</div><div>>>> sys.getsizeof(t.__dict__)</div><div>Traceback (most recent call last):</div><div> File "<stdin>", line 1, in <module></div>
<div>AttributeError: 'tuple' object has no attribute '__dict__'</div></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
So a named-tuple has 6+n (where "n" is the number of fields) extra<br>
attributes, but it seems that namedtuples & tuples seem to occupy<br>
the same amount of space (72).<br>
<br>
Additionally, pulling up a second console and issuing<br>
<br>
ps v | grep [p]ython<br>
<br>
shows the memory usage of the process as I perform these, and after<br>
them, and they both show the same usage (actual test was<br>
<br>
1) pull up a fresh python<br>
2) import sys, collections; A = collections.namedtuple('A',['x','y'])<br>
3) check memory usage in other window<br>
4a) x = (1,2)<br>
4b) x = A(1,2)<br>
5) check memory usage again in other window<br>
6) quit python<br>
<br>
performing 4a on one run, and 4b on the second run.<br>
<br>
Both showed identical memory usage as well (Debian Linux (Stable),<br>
stock Python 2.6.6) at the system level.<br></blockquote><div><br></div><div>Python uses memory pools for small memory allocations. I don't think it's possible to tell from the outside how much memory is being used at such a fine level.</div>
<div><br></div><div>Oscar</div></div>