cpythonjavagolang_cpython:列表对象(PyListObject)的扩容机制
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)的扩容机制相关推荐
- 算法—顺序表之列表的扩容机制(python实现)
顺序表中增加元素 在尾部增加元素:时间复杂度为O(1) 在任意位置插入元素:时间复杂度为O(n) 顺序表中删除元素 删除尾部元素:时间复杂度为O(1) 删除任意位置元素:时间复杂度为O(n) PY_S ...
- netty的零拷贝、架构设计、ByteBuf扩容机制详解
文章目录 1. netty高并发架构设计精髓 ①:主从.Reactor线程模型 ②:NIO多路复用非阻塞 ③:无锁串行化设计思想 ④:高可用.可扩展架构 ⑤:直接内存和零拷贝 ⑥:ByteBuf内存池 ...
- arraylist 的扩容机制_ArrayList详解
作者丨HUC南枫 来源丨甲哇技术栈(jiawa1024)ArrayList 的底层是数组队列,相当于动态数组.与 Java 中的数组相比,它的容量能动态增长.在添加大量元素前,应用程序可以使用ensu ...
- java基础巩固-宇宙第一AiYWM:为了维持生计,多高(多线程与高并发)_Part9~整起(单双列集合们、ArrayList 的扩容机制、HashMap、ConcurrentHashMap )
再进入正文之前,先看看集合相关操作的时间复杂度: 本故事源自于~ 开唠: PART0: 为什么突然蹦出集合这个玩意,就是因为咱们基础那里学的"数组"不够用~: 数组一般用来保存一组 ...
- ArrayList源码扩容机制分析
ArrayList源码&扩容机制分析 发上等愿,结中等缘,享下等福 文章目录 ArrayList源码&扩容机制分析 1. ArrayList 简介 1.1. Arraylist 和 V ...
- python列表的实现原理_Python列表对象实现原理
Python 列表对象实现原理 Python 中的列表基于 PyListObject 实现,列表支持元 素的插入.删除.更新操作,因此 PyListObject 是一个变长 对象(列表的长度随着元素的 ...
- hashmap 扩容是元素还是数组_HashMap的扩容机制---resize()
面试的时候闻到了Hashmap的扩容机制,之前只看到了Hasmap的实现机制,补一下基础知识,讲的非常好 原文链接: Hashmap是一种非常常用的.应用广泛的数据类型,最近研究到相关的内容,就正好复 ...
- 【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制
该文已加入开源文档:JavaGuide(一份涵盖大部分Java程序员所需要掌握的核心知识).地址:https://github.com/Snailclimb/JavaGuide. 一 先从 Array ...
- java hashmap扩容大小_HashMap的扩容机制以及默认大小为何是2次幂
HashMap的Put方法 HashMap的数据结构设计可以参考链接.接下来回顾HashMap的put(Key k, Value v)过程: (1)对 Key求Hash值,计算出Hash表下标,对应h ...
最新文章
- matlab中用于小数取整的函数的用法
- sqli-lab(16)
- 安装windows时loading files结束就重启_软网推荐:不用制作系统盘 也能安装新系统...
- 安全是什么意思_进衡水火车站要转着圈找门!这是什么意思……清扫车路边倒水 既浪费又不安全...
- ~~朴素dijkstra算法 (搜索与图论)(附模板题AcWing 849. Dijkstra求最短路 I)
- Android通知频道,通知点
- HDoj 1862
- ASP常用服务器获取各类信息汇总
- JAVA怎么开发一个胖客户端_胖客户端瘦客户端哑终端
- 链接形式的客服代码 QQ客服代码
- java pem 读取_java读取微信Pem格式证书对字段加密
- B002 - 基于嵌入式的老人定位追踪监测仪
- snprintf_s解释
- TabIndex的问题
- 内网服务器反弹映射到公网ip去访问
- Python 频数直方图
- SQL 如何去掉字段中千位的逗号(比如set @= '1,320.00' 想得到@= '1320.00' )
- C语言从小到大进行排序
- 我决定把一个收费视频课全免费公开了,今天起,慢慢放出“人人都需要的产品思维课”...
- 关于加减运算时能否使用等价无穷小的问题
热门文章
- 在Spring MVC应用程序中使用Bean Validation 1.1获得更好的错误消息
- Java 8 Lambdas –缺少脱离Java的链接
- 什么是PermGen泄漏?
- 使用Scala,Play和Akka连接到RabbitMQ(AMQP)
- Hadoop:简单介绍
- MySQL的存储引擎InnoDB,B+Tree数据结构索引的实现原理图(聚簇索引/聚集索引)
- 关于压缩工具 7z(7-zip) 如何设置压缩算法(选项 -m 的解读)
- 如何在 Ubuntu 14.04 和 12.04 上测试 systemd
- QPW 邀请日志表(tf_invite_log)
- linux l文件共享,llinux服务器文件共享的一种简单的方法