list object

可变对象头

ob_item: 指向分配的空间,元素是指针

allocated: 真实容量.

Objects/listobjects.c

/* Ensure ob_item has room for at least newsize elements, and set

* ob_size to newsize. If newsize > ob_size on entry, the content

* of the new slots at exit is undefined heap trash; it's the caller's

* responsibility to overwrite them with sane values.

* The number of allocated elements may grow, shrink, or stay the same.

* Failure is impossible if newsize <= self.allocated on entry, although

* that partly relies on an assumption that the system realloc() never

* fails when passed a number of bytes <= the number of bytes last

* allocated (the C standard doesn't guarantee this, but it's hard to

* imagine a realloc implementation where it wouldn't be true).

* Note that self->ob_item may change, and even if newsize is less

* than ob_size on entry.

*/

static int

list_resize(PyListObject *self, Py_ssize_t newsize)

{

PyObject **items;

size_t new_allocated, num_allocated_bytes;

Py_ssize_t allocated = self->allocated;

/* Bypass realloc() when a previous overallocation is large enough

to accommodate the newsize. If the newsize falls lower than half

the allocated size, then proceed with the realloc() to shrink the list.

*/

if (allocated >= newsize && newsize >= (allocated >> 1)) {

assert(self->ob_item != NULL || newsize == 0);

Py_SET_SIZE(self, newsize);

return 0;

}

/* 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.

*/

new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3;

/* Do not overallocate if the new size is closer to overallocated size

* than to the old size.

*/

if (newsize - Py_SIZE(self) > (Py_ssize_t)(new_allocated - newsize))

new_allocated = ((size_t)newsize + 3) & ~(size_t)3;

if (newsize == 0)

new_allocated = 0;

num_allocated_bytes = new_allocated * sizeof(PyObject *);

items = (PyObject **)PyMem_Realloc(self->ob_item, num_allocated_bytes);

if (items == NULL) {

PyErr_NoMemory();

return -1;

}

self->ob_item = items;

Py_SET_SIZE(self, newsize);

self->allocated = new_allocated;

return 0;

}

list resize

import sys

def print_list_size(nums=None):

nums_size = sys.getsizeof(nums)

if nums:

print(f"id({id(nums)}) v:{nums[-1]} len:{len(nums)} size:{nums_size}")

else:

print(f"id({id(nums)}) v:{nums} len:{len(nums)} size:{nums_size}")

def test_0_4():

data = []

print_list_size(nums=data)

for i in range(1, 35):

data.append(i)

print_list_size(nums=data)

test_0_4()

def resize_list(x):

return (x + (x >> 3) + 6) & (~3)

"""

## 3.9

Add padding to make the allocated size multiple of 4

The growth pattern is: 0, 4, 8, 16, 24, 32, 40, 52, 64, 76

https://github.com/python/cpython/blob/3.9/Objects/listobject.c

new_allocated = ((size_t)newsize + (newsize >> 3) + 6) & ~(size_t)3;

id(4554271168) v:[] len:0 size:56

id(4554271168) v:1 len:1 size:88

id(4554271168) v:2 len:2 size:88

id(4554271168) v:3 len:3 size:88

id(4554271168) v:4 len:4 size:88

id(4554271168) v:5 len:5 size:120

id(4554271168) v:6 len:6 size:120

id(4554271168) v:7 len:7 size:120

id(4554271168) v:8 len:8 size:120

id(4554271168) v:9 len:9 size:184

id(4554271168) v:10 len:10 size:184

id(4554271168) v:11 len:11 size:184

id(4554271168) v:12 len:12 size:184

id(4554271168) v:13 len:13 size:184

id(4554271168) v:14 len:14 size:184

id(4554271168) v:15 len:15 size:184

id(4554271168) v:16 len:16 size:184

id(4554271168) v:17 len:17 size:248

id(4554271168) v:18 len:18 size:248

id(4554271168) v:19 len:19 size:248

id(4539054528) v:20 len:20 size:248

id(4539054528) v:21 len:21 size:248

id(4539054528) v:22 len:22 size:248

id(4539054528) v:23 len:23 size:248

id(4539054528) v:24 len:24 size:248

id(4506298816) v:25 len:25 size:312

id(4506298816) v:26 len:26 size:312

id(4506298816) v:27 len:27 size:312

id(4506298816) v:28 len:28 size:312

id(4506298816) v:29 len:29 size:312

id(4506298816) v:30 len:30 size:312

id(4506298816) v:31 len:31 size:312

id(4506298816) v:32 len:32 size:312

id(4506298816) v:33 len:33 size:376

id(4506298816) v:34 len:34 size:376

## 3.7/3.8

The growth pattern is: 0, 4, 8, 16, 25, 35, 46, 58, 72, 88

https://github.com/python/cpython/blob/3.7/Objects/listobject.c

https://github.com/python/cpython/blob/3.8/Objects/listobject.c

new_allocated = (size_t)newsize + (newsize >> 3) + (newsize < 9 ? 3 : 6);

(py3) ➜ stu git:(hyh_debug_01_main) ✗ python --version

Python 3.7.4

(py3) ➜ stu git:(hyh_debug_01_main) ✗ python test_list_resize.py

id(4538606048) v:[] len:0 size:72

id(4538606048) v:1 len:1 size:104

id(4538606048) v:2 len:2 size:104

id(4538606048) v:3 len:3 size:104

id(4538606048) v:4 len:4 size:104 4个空间使用完. 增加4

id(4538606048) v:5 len:5 size:136

id(4538606048) v:6 len:6 size:136

id(4538606048) v:7 len:7 size:136

id(4538606048) v:8 len:8 size:136 8个空间使用完. 增加4

id(4538606048) v:9 len:9 size:200

id(4538606048) v:10 len:10 size:200

id(4538606048) v:11 len:11 size:200

id(4538606048) v:12 len:12 size:200

id(4538606048) v:13 len:13 size:200

id(4538606048) v:14 len:14 size:200

id(4538606048) v:15 len:15 size:200

id(4538606048) v:16 len:16 size:200 16个空间使用完. 增加8

id(4538606048) v:17 len:17 size:272

id(4538606048) v:18 len:18 size:272

id(4538606048) v:19 len:19 size:272

id(4538606048) v:20 len:20 size:272

id(4538606048) v:21 len:21 size:272

id(4538606048) v:22 len:22 size:272

id(4538606048) v:23 len:23 size:272

id(4538606048) v:24 len:24 size:272

id(4538606048) v:25 len:25 size:272 25个空间使用完. 增加9

id(4538606048) v:26 len:26 size:352

id(4538606048) v:27 len:27 size:352

id(4538606048) v:28 len:28 size:352

id(4538606048) v:29 len:29 size:352

id(4538606048) v:30 len:30 size:352

id(4538606048) v:31 len:31 size:352

id(4538606048) v:32 len:32 size:352

id(4538606048) v:33 len:33 size:352

id(4538606048) v:34 len:34 size:352

# 关于size不一致问题,_typeobject 类型对象结构体在py3.9中删除了部分元素比3.8更小

"""

cpythonjavagolang_cpython:列表对象(PyListObject)的扩容机制相关推荐

  1. 算法—顺序表之列表的扩容机制(python实现)

    顺序表中增加元素 在尾部增加元素:时间复杂度为O(1) 在任意位置插入元素:时间复杂度为O(n) 顺序表中删除元素 删除尾部元素:时间复杂度为O(1) 删除任意位置元素:时间复杂度为O(n) PY_S ...

  2. netty的零拷贝、架构设计、ByteBuf扩容机制详解

    文章目录 1. netty高并发架构设计精髓 ①:主从.Reactor线程模型 ②:NIO多路复用非阻塞 ③:无锁串行化设计思想 ④:高可用.可扩展架构 ⑤:直接内存和零拷贝 ⑥:ByteBuf内存池 ...

  3. arraylist 的扩容机制_ArrayList详解

    作者丨HUC南枫 来源丨甲哇技术栈(jiawa1024)ArrayList 的底层是数组队列,相当于动态数组.与 Java 中的数组相比,它的容量能动态增长.在添加大量元素前,应用程序可以使用ensu ...

  4. java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part9~整起(单双列集合们、ArrayList 的扩容机制、HashMap、ConcurrentHashMap )

    再进入正文之前,先看看集合相关操作的时间复杂度: 本故事源自于~ 开唠: PART0: 为什么突然蹦出集合这个玩意,就是因为咱们基础那里学的"数组"不够用~: 数组一般用来保存一组 ...

  5. ArrayList源码扩容机制分析

    ArrayList源码&扩容机制分析 发上等愿,结中等缘,享下等福 文章目录 ArrayList源码&扩容机制分析 1. ArrayList 简介 1.1. Arraylist 和 V ...

  6. python列表的实现原理_Python列表对象实现原理

    Python 列表对象实现原理 Python 中的列表基于 PyListObject 实现,列表支持元 素的插入.删除.更新操作,因此 PyListObject 是一个变长 对象(列表的长度随着元素的 ...

  7. hashmap 扩容是元素还是数组_HashMap的扩容机制---resize()

    面试的时候闻到了Hashmap的扩容机制,之前只看到了Hasmap的实现机制,补一下基础知识,讲的非常好 原文链接: Hashmap是一种非常常用的.应用广泛的数据类型,最近研究到相关的内容,就正好复 ...

  8. 【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制

    该文已加入开源文档:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识).地址:https://github.com/Snailclimb/JavaGuide. 一 先从 Array ...

  9. java hashmap扩容大小_HashMap的扩容机制以及默认大小为何是2次幂

    HashMap的Put方法 HashMap的数据结构设计可以参考链接.接下来回顾HashMap的put(Key k, Value v)过程: (1)对 Key求Hash值,计算出Hash表下标,对应h ...

最新文章

  1. matlab中用于小数取整的函数的用法
  2. sqli-lab(16)
  3. 安装windows时loading files结束就重启_软网推荐:不用制作系统盘 也能安装新系统...
  4. 安全是什么意思_进衡水火车站要转着圈找门!这是什么意思……清扫车路边倒水 既浪费又不安全...
  5. ~~朴素dijkstra算法 (搜索与图论)(附模板题AcWing 849. Dijkstra求最短路 I)
  6. Android通知频道,通知点
  7. HDoj 1862
  8. ASP常用服务器获取各类信息汇总
  9. JAVA怎么开发一个胖客户端_胖客户端瘦客户端哑终端
  10. 链接形式的客服代码 QQ客服代码
  11. java pem 读取_java读取微信Pem格式证书对字段加密
  12. B002 - 基于嵌入式的老人定位追踪监测仪
  13. snprintf_s解释
  14. TabIndex的问题
  15. 内网服务器反弹映射到公网ip去访问
  16. Python 频数直方图
  17. SQL 如何去掉字段中千位的逗号(比如set @= '1,320.00' 想得到@= '1320.00' )
  18. C语言从小到大进行排序
  19. 我决定把一个收费视频课全免费公开了,今天起,慢慢放出“人人都需要的产品思维课”...
  20. 关于加减运算时能否使用等价无穷小的问题

热门文章

  1. 在Spring MVC应用程序中使用Bean Validation 1.1获得更好的错误消息
  2. Java 8 Lambdas –缺少脱离Java的链接
  3. 什么是PermGen泄漏?
  4. 使用Scala,Play和Akka连接到RabbitMQ(AMQP)
  5. Hadoop:简单介绍
  6. MySQL的存储引擎InnoDB,B+Tree数据结构索引的实现原理图(聚簇索引/聚集索引)
  7. 关于压缩工具 7z(7-zip) 如何设置压缩算法(选项 -m 的解读)
  8. 如何在 Ubuntu 14.04 和 12.04 上测试 systemd
  9. QPW 邀请日志表(tf_invite_log)
  10. linux l文件共享,llinux服务器文件共享的一种简单的方法