python源码剖析笔记_python源码剖析笔记---PyListObject

1.PyListObject对象的定义

typedef struct {

PyObject_VAR_HEAD

PyObject **ob_item; //指向存储列表对象指针数组的首地址

int allocated;  //列表可以容纳的元素数目,注意这个和ob_size不同。ob_size表示已有元素数目,allocated表示能容纳的最多元素数目

} PyListObject;

说明:PyListObject和PyStringObject一样,都是变长对象,因此都有头PyObject_VAR_HEAD, 不同点是,PyStringObject是不可变对象,一旦创建,字符串内容不可改变;PyListObject则不同,可以再运行过程中动态删除、修改或新增元素。注意ob_size和allocated的关系:0 <= ob_size <= allocated

2.内存管理策略

每次申请内存是,PyListObject对象会申请一大块内存,而不是有多少元素申请多少元素,申请的总大小存储在allocated中。这样做是为了提高效率

3.修改、插入及删除操作

修改操作最简单,直接定位到相应位置替换掉对应位置的对象指针即可。如a = 100, ls[2] = a, 实际操作:(ls->ob_item + 2) = &a

插入操作:

对应两种操作,ls.insert(3, 'new value'); ls.append('new value'),这两个函数操作流程几乎相同

step1: 检查ls->ob_size和ls->allocated的关系,判断是否需要重新分配内存,如果ob_size < allocated,则无需重新分配内存,转step3,否则转step2重新分配内存(这一步并不完全,实际上还会检查如果allocated> 2*ob_size,也会重新分配内存,目的是释放过多的空闲内存)

step2:重新分配内存, 注意这步需要重新申请内存空间,然后将元ob_item的数据拷贝到新申请的空间

step3:在相应位置插入元素,其后所有元素需要往后移动.(这和C++中的Vector类似,插入操作效率较低)

删除操作:

删除操作将被删除对象对应的指针删除之后,其后的所有指针都要向前移动,和C++中的Vector类似,删除效率较低

注意:

删除操作可以删除单个元素,也可以删除片段,如del ls[1]; del ls[1 : 3]

替换也可以替换一个片段, 如ls[2:4] = [1,3,4,5],这个操作实际上是通过内存拷贝来实现

4.PyListObject缓冲池

Python系统会为List对象维护一个默认大小为80的对象缓冲池,每次创建新的List对象时,系统会坚持缓冲池中有没有空余空间,若有,则直接使用,重新围棋分配ob_item的空间,否则重新创建List对象。

该缓冲池初大小为0,在销毁List对象时会被分配空间。具体如下:

当销毁某List对象时,实际上分两步。第一步先销毁List维护的元素空间,即ob_item指向的内存空间,然后销毁List本身。当销毁完ob_item对应的空间之后,系统会检查缓冲池大小是否小于80,若小于80,系统不会真正销毁List对象本身,而是将其挂载到List缓冲区等待下次使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值