【问题标题】:Strange output sys.getsizeof()奇怪的输出 sys.getsizeof()
【发布时间】:2015-02-18 00:34:18
【问题描述】:

我刚刚运行了这些代码:

v = [1,2,'kite',100**100]

for x,y in enumerate(v):
    print ("{} size is: {}".format(y,sys.getsizeof(v[x])))
print ("Total size is: {} ".format(sys.getsizeof(v)))

输出:

1 size is: 14
2 size is: 14
kite size is: 29
100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 size is: 102
Total size is: 52 
>>>

v的最后一个元素大小是102,总大小是52?同样即使没有最后一个元素,列表的前 3 个元素的总和仍然大于总大小,我的问题是为什么? Python 在列表中执行 zip 处理?

另一个奇怪的是,在这个输出之间;

v = [""]

for x,y in enumerate(v):
    print ("{} size is: {}".format(y,sys.getsizeof(v[x])))
print ("Total size is: {} ".format(sys.getsizeof(v)))

v=[" "]
for x,y in enumerate(v):
    print ("{} size is: {}".format(y,sys.getsizeof(v[x])))
print ("Total size is: {} ".format(sys.getsizeof(v)))

输出:

>>> 
 size is: 27
Total size is: 40 
  size is: 26
Total size is: 40 
>>>

真的很奇怪,谁能解释一下是怎么回事?

【问题讨论】:

标签: python list python-3.x size sys


【解决方案1】:

来自documentation(我的粗体字)(a)

仅考虑直接归因于对象的内存消耗,不考虑它所引用的对象的内存消耗。

所以v 的大小包括它所指的元素的大小。

如果您将kite 更改为kites,您将看到它的大小增加了,但没有v 的大小(我已替换你的大数字在输出中带有100...00 以便于格式化):

1 size is: 12
2 size is: 12
kite size is: 25
100...00 size is: 102
Total size is: 48

1 size is: 12
2 size is: 12
kites size is: 26
100...00 size is: 102
Total size is: 48

这样想:

       /  +-----+
      | v | ref | -> 1
Size  |   | ref | -> 2
 of v |   | ref | -> 'kite'
      |   | ref | -> 100**100
       \  +-----+
                     \___________________________/
                      Size of things referred
                       to by v

(a) 如果您需要该信息,该页面还包含一个指向用于进行递归大小计算的方法的链接。链接重复here 以供引用,代码在下面重复以使此答案更加独立。

将你的结构插入到该代码中:

48 <type 'list'> [1, 2, 'kites', 100...00L]
12 <type 'int'> 1
12 <type 'int'> 2
26 <type 'str'> 'kites'
102 <type 'long'> 100...00L
200

代码和你的结构如下所示。

from __future__ import print_function
from sys import getsizeof, stderr
from itertools import chain
from collections import deque
try:
    from reprlib import repr
except ImportError:
    pass

def total_size(o, handlers={}, verbose=False):
    """ Returns the approximate memory footprint an object and all of its contents.

    Automatically finds the contents of the following builtin containers and
    their subclasses:  tuple, list, deque, dict, set and frozenset.
    To search other containers, add handlers to iterate over their contents:

        handlers = {SomeContainerClass: iter,
                    OtherContainerClass: OtherContainerClass.get_elements}

    """
    dict_handler = lambda d: chain.from_iterable(d.items())
    all_handlers = {tuple: iter,
                    list: iter,
                    deque: iter,
                    dict: dict_handler,
                    set: iter,
                    frozenset: iter,
                   }
    all_handlers.update(handlers)     # user handlers take precedence
    seen = set()                      # track which object id's have already been seen
    default_size = getsizeof(0)       # estimate sizeof object without __sizeof__

    def sizeof(o):
        if id(o) in seen:       # do not double count the same object
            return 0
        seen.add(id(o))
        s = getsizeof(o, default_size)

        if verbose:
            print(s, type(o), repr(o), file=stderr)

        for typ, handler in all_handlers.items():
            if isinstance(o, typ):
                s += sum(map(sizeof, handler(o)))
                break
        return s

    return sizeof(o)


##### Example call #####

if __name__ == '__main__':
    v = [1,2,'kites',100**100]
    print(total_size(v, verbose=True))

【讨论】:

    【解决方案2】:

    发生这种情况是因为您的“总大小”实际上是没有内容的列表结构的大小。所以你可以在那里存储任何大小的对象,它不会改变你的“总大小”。您需要一个“递归”getsizeof(),为此,请参见此处:Python deep getsizeof list with contents? 或此处:Deep version of sys.getsizeof

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-03
      • 2011-06-14
      • 2013-06-04
      • 2021-02-08
      • 2014-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多