在python中,array.array插入是如何在后台工作的



在python中,array.array是一个可变结构。

但是,我不确定插入操作在array.array结构中是如何工作的。

由于array.array使用连续内存,如果新元素不能以连续方式放置,它是否会创建一个新的内存块并复制数组的所有元素?它是否为插入操作预留了额外的未使用空间?

Listing[Python3.Docs]:数组-数值的高效数组,以防万一。

任何一个体面的容器都可以将数据保存在一个连续的内存区域中,分配的内存超过了保存当前元素数量所需的内存
如果在插入(附加是一种特殊情况(一个元素时没有额外元素的空间,会发生什么:

  1. 分配内存区域(当前大小+1(元素大小((
  2. 将数据复制到新区域
  3. 免费旧区
  4. 无论如何都要执行其他小操作(如大小(计数器(更新…(

如图所示,在追加(这是添加元素的最常见操作(时,会有大量工作需要时间和资源(CPU电源、内存(。

现代容器有一个不断增长的策略算法:每次需要重新分配内存区域(容器已满(时,都会在现有大小上添加一个N元素来计算新大小,而且更多:每次重新分配时,N都会变大。这是为了最大限度地减少(昂贵的(内存操作
当然,在间隔的另一端,可能会为一个容器分配大量内存(例如500 MiB(,但这是不可行的,因为大量内存将"保留"在那里,以备拥有容器可能需要。
毕竟,这只是一个折衷的问题。

您可以检查[CPPReference]:std::vector作为示例(大小容量方法(。

回到我们的问题:array.array确实是一个分配未使用空间的现代容器。来自[GitHub]:python/cpython-(master(cpython/Modules/arraymodule.c:

/* This over-allocates proportional to the array 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, 34, 46, 56, 67, 79, ...
* Note, the pattern starts out the same as for lists but then
* grows at a smaller rate so that larger arrays only overallocate
* by about 1/16th -- this is done because arrays are presumed to be more
* memory critical.
*/
于插入算法本身,请检查ins1函数:
  • 检查(并更新(大小,如果需要,会增加内存
  • 插入位置之后的元素将向一端("右侧"(移动一个位置
  • 新元素被放置在插入位置

顺便说一句,其他Python容器都使用这种技术,请检查[SO]:为什么列表会询问__len__?(@CristiFati的回答(了解更多细节。

最新更新