代码之家  ›  专栏  ›  技术社区  ›  jfs

Python列表(元组)中每个元素有多少字节?

  •  13
  • jfs  · 技术社区  · 17 年前

    例如,存储一百万(32位)整数的列表需要多少内存?

    alist = range(1000000) # or list(range(1000000)) in Python 3.0
    
    6 回复  |  直到 17 年前
        1
  •  24
  •   Dan Lenski    17 年前

    Python为列表分配空间的方式是为了实现 amortized constant time 用于将元素附加到列表。

    在实践中,这意味着当前的实施是。。。列表总是为两个元素的幂分配空间。所以range(1000000)实际上会分配一个足够容纳2^20个元素(约104.5万个)的列表。

    这只是存储列表结构本身所需的空间(它是指向每个元素的Python对象的指针数组)。32位系统每个元素需要4个字节,64位系统每个元素需要8个字节。

    此外,您需要空间来存储实际的元素。这方面的差异很大。对于较小的整数(-5到256),不需要额外的空间,但是对于较大的整数,Python会为每个整数分配一个新的对象,它需要10到100个字节,并且倾向于分割内存。

    底线: 这很复杂 Python列表是 存储大型同质数据结构的好方法。为此,请使用 array 模块,或者,如果需要进行矢量化数学,请使用NumPy。

    与列表不同,PS-元组是 非设计 使元素逐渐附加到它们上。我不知道分配器是如何工作的,但我甚至不考虑将其用于大型数据结构:-)

        2
  •  15
  •   jfs    17 年前

    有用链接:

    How to get memory size/usage of python object

    Memory sizes of python objects?

    if you put data into dictionary, how do we calculate the data size?

    然而,他们没有给出一个明确的答案。前进之路:

    1. 测量Python解释器使用/不使用列表所消耗的内存(使用OS工具)。

    2. 使用第三方扩展模块,该模块定义某种类型的sizeof(PyObject)。

    使现代化 :

    Recipe 546530: Size of Python objects (revised)

    import asizeof
    
    N = 1000000
    print asizeof.asizeof(range(N)) / N
    # -> 20 (python 2.5, WinXP, 32-bit Linux)
    # -> 33 (64-bit Linux)
    
        3
  •  6
  •   Constantin    17 年前

    解决问题的“元组”部分

    在典型的构建配置中声明CPython的PyTuple归结为:

    struct PyTuple {
      size_t refcount; // tuple's reference count
      typeobject *type; // tuple type object
      size_t n_items; // number of items in tuple
      PyObject *items[1]; // contains space for n_items elements
    };
    

    PyTuple实例的大小在构建过程中是固定的,以后不能更改。PyTuple占用的字节数可以计算为

    sizeof(size_t) x 2 + sizeof(void*) x (n_items + 1) .

    浅的 大小您还需要添加根目录中的对象图所消耗的总字节数 PyTuple::items[] 大堆

    参考资料: Python.h , object.h , tupleobject.h , tupleobject.c

        4
  •  4
  •   Constantin    17 年前

    新功能,, getsizeof() ,需要一个 Python对象,并返回金额 以字节为单位。内置对象返回 正确的结果;第三方 __sizeof__() 方法返回对象大小。

    kveretennicov@nosignal:~/py/r26rc2$ ./python
    Python 2.6rc2 (r26rc2:66712, Sep  2 2008, 13:11:55) 
    [GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
    >>> import sys
    >>> sys.getsizeof(range(1000000))
    4000032
    >>> sys.getsizeof(tuple(range(1000000)))
    4000024
    

        5
  •  2
  •   HenryR    17 年前

    在我的Python上(Fedora9上的2.5.1在Core2Duo上),分配前的VmSize为6896kB,分配后的VmSize为22684kB。再分配一百万个元素后,VmSize将变为38340kB。这非常明显地表明1000000个整数大约有16000kB,即每个整数大约有16个字节。这意味着 大量 列表的开销。我对这些数字不屑一顾。