python数据类型的内部实现和内存分析

http://blog.csdn.net/pipisorry/article/details/23624041?locationNum=5&fps=1

Python中基本数据类型占的字节数

下面的测试都是64位系统,python3输出的结果

Python 对象内存占用

sys.getsizeof()或者i.__sizeof__()

Python 在 sys 模块中提供函数 getsizeof 来计算 Python 对象的大小。
    sys.getsizeof(object[, default])
    以字节(byte)为单位返回对象大小。 这个对象可以是任何类型的对象。 所以内置对象都能返回正确的结果 但不保证对第三方扩展有效,因为和具体实现相关。
    getsizeof() 调用对象的 __sizeof__ 方法, 如果对象由垃圾收集器管理, 则会加上额外的垃圾收集器开销。

In[2]: sys.getsizeof(True)
28


>>> i = 1

>>> i.__sizeof__()
28

In[3]: sys.getsizeof(1)
28

Python语言的整型相当于C语言中的long型,在32位机器上,整型的位宽为32位,取值范围为 -2147483648~2147483647;在64位系统上,整型的位宽通常为64位,取值范围为-9223372036854775808~9223372036854775807 (2^63-1)


In[4]: sys.getsizeof(1.0)
24
In[5]: sys.getsizeof('1')
58

In[9]: i = str(1)
In[10]: sys.getsizeof(i)
50


In[6]: sys.getsizeof([])
64
In[7]: sys.getsizeof([1])
72
In[8]: sys.getsizeof(['1'])
72

可见列表最少占用36个字节,每增加一个元素,增加4个字节。但要注意,sys.getsizeof 函数并不计算容器类型的元素大小。容器中保存的应该是对元素的引用。可以看出列表的空间占用为 基本空间 64 + (对象引用 8 + 对象大小) * 元素个数。


sys.getsizeof(())
48
sys.getsizeof(tuple())
48
sys.getsizeof(set())
224
sys.getsizeof({})
288
sys.getsizeof(dict())
288

sys.getsizeof(type)
400

[Python 对象内存占用]

numpy对象内存占用

In[2]: np.array([]).__sizeof__()
96
In[3]: np.array([1]).__sizeof__()
104
In[4]: np.array(['1']).__sizeof__()
100
In[5]: np.array([str(1)]).__sizeof__()
100

In[6]: np.array([1.1]).__sizeof__()
104

numpy array就相当于c语言中的数组,可以看出int类型的数据占用的实际内存为8bytes。并且array存储的是值而不是引用。

[ numpy教程:numpy基本数据类型及多维数组元素存取]

皮皮blog



python列表内存分析

在Python中,列表是一个动态的指针数组。列表是动态数组,因此往其中添加新元素,而没有空间保存新的元素时,它们会自动重新分配内存块,并将原来的内存 中的值复制到新的内存块中。为了减少重新分配内存的次数,通常每次重新分配时,大小都为原来的k倍。k值越大,则重新分配内存的次数越少,但浪费的空间越多。

a = []

a.__sizeof__()
40
a.append(1)
a.__sizeof__()
72
a.append(2)
a.__sizeof__()
72
a.extend([3,4])
a.__sizeof__()
72
a.append(5)
a.__sizeof__()
104

a.extend([6,7,8,9,10])

a.__sizeof__()

176

Note: lz使用64位机py3测试的,一个int型应该是占用8bytes字节。

通过getsizeof()计算列表的增长模式

sys.getsizeof()可以获得列表所占用的内存大小。图中每个阶梯跳变的位置都表示一次内存分配,而每个阶梯的长度表示内存分配多出来的大小。

由图可知曲线呈指数增长,第45次分配内存时,列表的大小已经接近10000。


为了计算增长率,只需要计算resize_pos数组前后两个值的商的平均值即可。


array对象添加每个元素所需的时间

[Python科学计算习题集研究list和array的内存增长模式]

[Python中list的实现]

皮皮blog



python array类型内存分析

[python模块:array数组模块 ]

python dict内部实现及分析

实现结构:哈希表(也叫散列表),根据关键值对(Key-value)而直接进行访问的数据结构。

解决冲突通常的做法有两种,一种是链接法,另一种是开放寻址法,Python选择后者。

搜寻空闲槽用到了一个二次探测序列(quadratic probing sequence),其代码如下:

j = (5*j) + 1 + perturb;
perturb >>= PERTURB_SHIFT;
use j % 2**i as the next table index;

循环地5*j+1可以快速放大不影响初始索引的哈希值二进位的微小差异。变量perturb可使其他二进位也不断变化。

Note: 查算法导论,也可以使用如双重散列h(k,i) = (h1(k) + i*h2(k)) mod m,为了查找整个表,值h2(k)必须要与表的大小m互素。一种方法是m取2的幂,并设计一个总产生奇数的h2。

[深入 Python 字典的内部实现]

[Python字典对象实现原理]

[使用python的list实现python dict 一入python深似海--dict(字典)的一种实现 ]

from: http://blog.csdn.net/pipisorry/article/details/23624041?locationNum=5&fps=1

ref:


  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值