Python缓冲池初探

本文探讨了Python编程语言中设置缓冲池的原因,包括降低对象创建撤销频率和减少内存使用。重点讲解了缓冲池的实现,特别是针对小整数对象池的理解,强调了不可变对象如字符串如何利用缓冲池。同时,文章指出浮点数没有内置缓冲池,但可以通过动态进出池方式实现缓冲。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.首先说下自己对编程语言中为什么要设置缓冲池(i.e.缓冲池的作用)

1.降低'常用'对象频繁创建撤销频率(PS:个人认为这里的常用是语言设计者的经验之举同样也是一厢情愿之举)

2.减少内存使用(i.e.降低内存占用)

2.再说下自己对缓冲池实现的理解及哪些类型能使用缓冲池

2.1.对缓冲池实现的理解

1.缓冲池实际上就是当python解释器启动时所开辟内存空间中的一部分,用语存储高频使用的对象

2.2哪些类型能使用缓冲池

1.可变对象(对象是python对数据的抽象,所有数据都以对象或对象间关系表示)肯定没戏,因为随时可能被修改,因而对其缓存是没有意义的

2.不可变对象

1.缓冲池大小受内存制约可定是有一定范围的(缓存范围)

2.可以动态的进出池来实现对有限缓冲内存的有效合理利用


一.可变对象

# 列表
l1 = [1, 2]
l2 = [1, 2]
print('列表: ', id(l1), id(l2))

# 字典
d1 = {1:'1', '2':2}
d2 = {1:'1', '2':2}
print('字典: ' , id(d1), id(d2))

'''
输出:
	列表:  2341086927880 2341086926856
	字典:  2341086055088 2341086055160
'''

上面已经说过了,可变对象不可能使用缓冲池,因可变对象随时可变,缓存是没有意义的

二.不可变对象

1.元组不适用于实现缓冲池机制(因为tuple是复合对象)

# 元组
tup1 = (1, 2)
tup2 = (1, 2)
print('元组: ', id(tup1), id(tup2))
'''
输出:
	元组:  2216663708168 2216663708232
'''
元组虽然是不可变对象,但是其元素可以是可变对象,即元组是不可变对象其元素不可变但其元素的元素可能变化

例如:

l = [1, 2, 3]
t = (1, 2, l)
print(t, id(t), id(t[2]))
t[2].append('变')
print(t, id(t), id(t[2]))
'''
输出:
	(1, 2, [1, 2, 3]) 		1997111491608 1997111532552
	(1, 2, [1, 2, 3, '变']) 1997111491608 1997111532552
'''
可以看到,虽然元组是不可变类型,即其元不可变(赋值,修改),但是其元素的元素可能改变,因而缓存也是没有意义的

2.字符串

PS:个人理解字符串的缓冲池是通过动态的进出池实现的

# 字符串
s1 = 'ab'
s2 = 'ab'
print('字符串: ', id(s1), id(s2))
s1 = 'ab' + 'c'
s2 = 'ab' + 'c'
print('字符串: ', id(s1), id(s2))
3.数值

# int数值型
i1 = -5
i2 = -5
print('int负数: ', id(i1), id(i2))
i1 = -6
i2 = -6
print('int负数: ', id(i1), id(i2))
i1 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
i2 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
print('int正数: ', id(i1), id(i2))
i1 = 2 ** 8
i2 = 2 ** 8
print('int正数: ', id(i1), id(i2))
i1 = 2 ** 9
i2 = 2 ** 9
print('int正数: ', id(i1), id(i2))

# float数值型
f1 = -0.0
f2 = -0.0
print('float负数: ', id(f1), id(f2))
f1 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999.12
f2 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999.12
print('float正数: ', id(f1), id(f2)) 
f1 = 2.1 ** 2
f2 = 2.1 ** 2
print('float正数: ', id(f1), id(f2))

'''
输出:
	int负数:  1963242368 1963242368
	int负数:  2091118590896 2091118590928
	int正数:  2091118694312 2091118694312
	int正数:  1963250720 1963250720
	int正数:  2091118590960 2091118590992
	float负数:  2091086189000 2091086189096
	float正数:  2091086188808 2091086188808
	float正数:  2091086189120 2091086189144
'''

下面对结果进行苦逼的分析(PS:全都是个人理解,欢迎指正)

int负数:  1963242368 1963242368

int负数:  2091118590896 2091118590928

上述两条对比是想说明python对int型的负值的缓冲范围最小值是-5

int正数:  2091118694312 2091118694312
int正数:  1963250720 1963250720

int正数:  2091118590960 2091118590992

上述三条对比是想说明python中对int型的正直的缓冲范围最大值是2**8,同时支持动态进出池实现缓冲

float负数:  2091086189000 2091086189096

上述一条说明python对浮点数没有实现缓冲池(这里说的是像int那样的內建缓冲池[-5, 256]即一个字节大小的缓冲池,而不是通过动态进出池来实现的缓冲池)

float正数:  2091086188808 2091086188808

上述一条说明python对浮点数的缓冲池实现是通过动态进出池实现缓冲

float正数:  2091086189120 2091086189144

因为浮点数不能精确表示,所以相同的操作数计算后结果可能是不想等的,即认为结果是两个对象才是合理的







个人认知有限,欢迎指正....持续更新2017年5月19日20:38:29


-----第一次更新----2018年3月8日19:03:53

1.小整数对象池: [-5, 256]

2.单个ASCII码字符池:  参见<http://www.asciima.com/>

3.inter机制:  英文字符串池

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值