Python缓冲池初探

来源:互联网 发布:软件著作权 发表状态 编辑:程序博客网 时间:2024/05/22 06:14

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 = -5i2 = -5print('int负数: ', id(i1), id(i2))i1 = -6i2 = -6print('int负数: ', id(i1), id(i2))i1 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999i2 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999print('int正数: ', id(i1), id(i2))i1 = 2 ** 8i2 = 2 ** 8print('int正数: ', id(i1), id(i2))i1 = 2 ** 9i2 = 2 ** 9print('int正数: ', id(i1), id(i2))# float数值型f1 = -0.0f2 = -0.0print('float负数: ', id(f1), id(f2))f1 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999.12f2 = 999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999.12print('float正数: ', id(f1), id(f2)) f1 = 2.1 ** 2f2 = 2.1 ** 2print('float正数: ', id(f1), id(f2))'''输出:int负数:  1963242368 1963242368int负数:  2091118590896 2091118590928int正数:  2091118694312 2091118694312int正数:  1963250720 1963250720int正数:  2091118590960 2091118590992float负数:  2091086189000 2091086189096float正数:  2091086188808 2091086188808float正数:  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