1. 程式人生 > >Python緩衝池初探

Python緩衝池初探

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機制:  英文字元串池