Any problems with *lots* of attributes?

Frank Millman frank at chagford.com
Thu Feb 5 02:27:39 EST 2004


> Frank Millman <frank at chagford.com> wrote:
> >
> >This is a question about the performance trade-off between two methods
> >of storing data. One method is to create a separate attribute for each
> >piece of data, and get/set the value according to its name. Another
> >method is to create a list, and get/set the value according to its
> >position in the list. In my limited tests, the first method is quicker.

Aahz <aahz at pythoncraft.com> wrote:
> 
> That doesn't make any sense.  While lists and dicts are both essentially
> O(1) for access, the constant is larger for dicts.  Please show us your
> testing code.
> 
Code shown below, but here is a summary -

print f.getval_from_attr()
print f.getval_from_list()
print f.setval_in_attr(1000)
print f.setval_in_list(1000)

Results, to 2 decimal places, are as follows -

0.32
0.45
0.34
0.44

> OTOH, there's certainly nothing wrong with using dicts; they are the
> single most fundamental Python data type after strings.  (All Python
> name/attribute access is built on top of dicts.)

This is exactly my point, but I may be misunderstanding how it works
internally. If I have a class with 20 attributes, it will have a
dictionary with 20 entries. If I have hundreds of instances of the
class, do I end up with hundreds of dictionaries (or the equivalent
internal structures), and if so, does this not lead to memory bloat?
If I store the data in a list, there will only be one dictionary entry
per instance. On the other hand, I suppose there must be some
reference to each of the elements of each list, so maybe there is an
equivalent overhead. Is this a valid concern, or am I worrying about
nothing?

Thanks for your input. Test program is shown below.

Frank

-------------------------------------

from time import time

class frank:
    def __init__(self,a,b,c,l):
        self.a = a  # an attribute
        self.b = b  # an attribute
        self.c = c  # an attribute
        self.l = l  # a list

    def getval_from_attr(self):
        start = time()
        for i in xrange(1000000):
            aa = self.a
        return (time() - start)

    def getval_from_list(self):
        start = time()
        for i in xrange(1000000):
            aa = self.l[0]
        return (time() - start)

    def setval_in_attr(self,val):
        start = time()
        for i in xrange(1000000):
            self.a = val
        return (time() - start)

    def setval_in_list(self,val):
        start = time()
        for i in xrange(1000000):
            self.l[0] = val
        return (time() - start)

f = frank(100,200,300,[100,200,300])
print f.getval_from_attr()
print f.getval_from_list()
print f.setval_in_attr(1000)
print f.setval_in_list(1000)

-------------------------------------

Results, to 2 decimal places, are as follows -

0.32
0.45
0.34
0.44



More information about the Python-list mailing list