Python字典大小与对象大小效率

2024-09-28 17:22:57 发布

您现在位置:Python中文网/ 问答频道 /正文

有人能解释一下在下面的例子中,当使用dictionaryobjects操作时,内存在幕后发生了什么吗

In [52]: class O(object):
....:         var1 = 'asdfasdfasfasdfasdfasdfasdf'
....:         var2 = 255
....: 

In [53]: dt = {'var1': 'asdfasdfasfasdfasdfasdfasdf', 'var2': 255}

In [55]: o = O()

In [57]: sys.getsizeof(o)
Out[57]: 64

In [58]: sys.getsizeof(dt)
Out[58]: 280

根据上述数值,接下来的事情很奇怪

In [68]: sys.getsizeof(o.var1)
Out[68]: 64

In [69]: sys.getsizeof(o.var2)
Out[69]: 24

In [70]: sys.getsizeof(dt['var1'])
Out[70]: 64

In [71]: sys.getsizeof(dt['var2'])
Out[71]: 24

数据结构中的值大小相同,但类型之间的差异让我想知道在幕后会发生什么?你知道吗

这个例子是否使objectsdictionaries更有效?你知道吗

我使用的是ubuntu14.04和python2.7.6


Tags: indictionaryobjectsobjectsysdtoutclass
2条回答

注意,^{}给出了对象本身的大小,但这并不是全部。一个对象具有各种属性,这些属性也会影响整个内存占用。例如,一个类的实例有一个__dict__,它保存其属性的值:

>>> o = O()
>>> o.__dict__
{}
>>> sys.getsizeof(o.__dict__)
140

注意三件有趣的事:

  1. 这也是一个字典-这个数据结构在Python中被大量使用,因此得到了非常好的优化
  2. o.__dict__中没有任何内容,因为var1var2类属性,存储在O,而不是实例属性;并且
  3. 尽管o.__dict__中没有任何内容,但它的大小仍然与dt相同,因为字典的初始化空间足以容纳(IIRC)8个键,以避免在向字典添加项时频繁调整大小(有关字典实现的更多信息,请参阅"The Mighty Dictionary")。你知道吗

另请注意,如果我们比较两种情况下的实例和类的大小(这是一个更公平的比较),差距就会缩小:

>>> sys.getsizeof(o) + sys.getsizeof(O)
484
>>> sys.getsizeof(dt) + sys.getsizeof(dict)
576

Does the example makes objects more effective over dictionaries?

一点也不;首先,如我所示,对象通常是使用字典来实现的(有一种方法可以通过在类上定义__slots__预定义属性来避免为每个实例创建__dict__,但我在这里就不谈了),字典本身就是对象(尽管内置类型略有不同,原因我就不多说了)!你知道吗

一般来说,除非出现问题,否则不要担心内存细节—如果需要state行为(attributes方法),请定义一个类;如果只需要state,请使用字典。你知道吗

两个对象的简单比较表明dictionary远比简单类复杂:

>>> dt = {}
>>> dir(dt)
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__',  
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__',  
'__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__',  
'__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__',  
'__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get',  
'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem',  
'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues']

反对:

>>> class O(object):
...   var1 = 'asdfasdfasfasdfasdfasdfasdf'
...   var2 = 255
... 
>>> o = O()
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', 
 '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__',  
'__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',  
'__str__', '__subclasshook__', '__weakref__', 'var1', 'var2']

相关问题 更多 >