2017-07-24 65 views
6

我讀過約Raymond Hettinger's new method實施compact dicts。這就解釋了爲什麼Python 3.6中的字典使用的內存少於Python 2.7-3.5中的字典。不過,Python 2.7和3.3-3.5版本的內存似乎有區別。測試代碼:爲什麼Python2.7字典使用比Python3字典更多的空間?

import sys 

d = {i: i for i in range(n)} 
print(sys.getsizeof(d)) 
  • Python 2.7版:12568
  • 的Python 3.5:6240
  • 的Python 3.6:4704

如前所述我理解3.5和3.6之間的儲蓄,但很好奇節省的原因在2.7和3.5之間。

+0

嗯,從來沒有注意到這一點,很好找。我不確定是否做出了改變,所以普通字典可以從組合表格中受益(請參閱我在此處做過的問答)(https://stackoverflow.com/questions/42419011/why-is-the-dict- python-3)在實例dicts上),但它可能是值得研究的。我懷疑它,但:-) –

回答

9

原來這是一隻紅鯡魚。增加字節大小的規則在cPython 2.7 - 3.2和cPython 3.3之間以及在cPython 3.4中改變(儘管這種改變只適用於刪除時)。我們可以使用下面的代碼,以確定看到這個當字典擴展:

import sys 

size_old = 0 
for n in range(512): 
    d = {i: i for i in range(n)} 
    size = sys.getsizeof(d) 
    if size != size_old: 
     print(n, size_old, size) 
    size_old = size 

的Python 2.7:

(0, 0, 280) 
(6, 280, 1048) 
(22, 1048, 3352) 
(86, 3352, 12568) 

的Python 3.5

0 0 288 
6 288 480 
12 480 864 
22 864 1632 
44 1632 3168 
86 3168 6240 

的Python 3.6:

0 0 240 
6 240 368 
11 368 648 
22 648 1184 
43 1184 2280 
86 2280 4704 

請記住,dicts調整w如果它們滿足2/3,我們可以看到cPython 2.7 dict的實現在擴展時增加了四倍,而cPython 3.5/3.6 dict的實現只增加了一倍。

這在dict source code評論解釋:

/* GROWTH_RATE. Growth rate upon hitting maximum load. 
* Currently set to used*2 + capacity/2. 
* This means that dicts double in size when growing without deletions, 
* but have more head room when the number of deletions is on a par with the 
* number of insertions. 
* Raising this to used*4 doubles memory consumption depending on the size of 
* the dictionary, but results in half the number of resizes, less effort to 
* resize. 
* GROWTH_RATE was set to used*4 up to version 3.2. 
* GROWTH_RATE was set to used*2 in version 3.3.0 
*/ 
+0

這將是很好,如果雷蒙德Hettinger看到這個問題,並告訴我們爲什麼他們做出了這樣的改變... –

+0

@ PM2Ring我有[下一個最好的事情](https:// www。 youtube.com/watch?v=p33CVV29OG8&feature=youtu.be&t=21m57s) – Alex