【问题标题】:Why do lists with the same data have different sizes?为什么具有相同数据的列表具有不同的大小?
【发布时间】:2018-03-24 02:58:46
【问题描述】:

假设我以两种方式创建 python lists

在第一种情况下,我使用简单的赋值:

my_list = []
print(my_list, '->', my_list.__sizeof__())
my_list = [1]
print(my_list, '->', my_list.__sizeof__())
my_list = [1, 1]
print(my_list, '->', my_list.__sizeof__())

在第二种情况下,我在列表中使用append() 方法:

my_list = []
print(my_list, '->', my_list.__sizeof__())
my_list.append(1)
print(my_list, '->', my_list.__sizeof__())
my_list.append(1)
print(my_list, '->', my_list.__sizeof__())

但我得到了意想不到的(对我来说)输出:

=== WITH ASSIGNMENT ===
([], '->', 40)
([1], '->', 48)
([1, 1], '->', 56)
=== WITH APPEND ===
([], '->', 40)
([1], '->', 72)
([1, 1], '->', 72)

Python 内存管理内部会发生什么?为什么“相同”的列表有不同的大小?

【问题讨论】:

标签: python python-2.7 list python-internals


【解决方案1】:

当您追加到列表时,由于性能原因,内存被过度分配给列表,因此多次追加不需要为列表重新分配相应的内存,这会降低整体性能重复追加的情况。

CPython 源代码在 comment 中清楚地描述了这种行为:

/* This over-allocates proportional to the list size, making room
 * for additional growth.  The over-allocation is mild, but is
 * enough to give linear-time amortized behavior over a long
 * sequence of appends() in the presence of a poorly-performing
 * system realloc().
 * The growth pattern is:  0, 4, 8, 16, 25, 35, 46, 58, 72, 88, ...
 * Note: new_allocated won't overflow because the largest possible value
 *       is PY_SSIZE_T_MAX * (9 / 8) + 6 which always fits in a size_t.
 */

在另一种情况下,列表由文字构成,列表的大小反映了容器本身的大小以及对每个包含对象的引用。

确切的分配行为可能因其他 Python 实现而异(请参阅 JythonPyPylist.append 实现)并且不保证存在过度分配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-18
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2018-06-16
    • 2012-08-20
    • 2011-10-02
    • 1970-01-01
    相关资源
    最近更新 更多