我一直试图更好地理解在通过追加扩展列表时,Python如何为列表分配内存.这question很好地涵盖了基本内容,并解释了随着列表长度的增加,内存增量的大小增加的原因.这article是对可以找到here的源代码的解释.
我想问一下这个解释:
/* 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(). * Add padding to make the allocated size multiple of 4. * The growth pattern is: 0, 4, 8, 16, 24, 32, 40, 52, 64, 76, ... * 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. */ 新分配=((大小_t)新大小+(新大小;&>3)+6)&;~(大小_t)3; /* Do not overallocate if the new size is closer to overallocated size * than to the old size. */
具体来说,这个计算:
新分配=((大小_t)新大小+(新大小;&>3)+6)&;~(大小_t)3;
我对这个计算的理解是,新的内存分配将等于newsize(触发增加的当前大小)+newsize右滚三位(有效除以8)+6. 然后将其与1的补数3进行AND运算,因此最后两位被强制为零,以使该值可被4整除.
我使用这个代码生成我的列表并报告大小:
a = [i for i in range(108)]
print(sys.getsizeof(a)) # 920 bytes
b = [i for i in range(109)]
print(sys.getsizeof(b)) # 1080 bytes
在109个元素时,触发了重新调整大小,此时newsize等于928字节
The calculation above should look like this:
1048字节小于报告的1060字节大小.
文档指出,这个过程可能不适合小列表,所以我try 了一个更大的列表. 我不会用二进制复制这个.
a = [i for i in range(10640)]
print(sys.getsizeof(a)) # 85176 bytes
b = [i for i in range(10641)]
print(sys.getsizeof(b)) # 95864 bytes
[85184+(86184>;>3)+6]=95838bytes
当应用"~3"时,该值将下降到95836.& 第95864章报道
为什么报告的大小大于计算的大小?