2017-07-24 5 views
6

Ich habe über Raymond Hettinger's new method der Implementierung compact dicts gelesen. Dies erklärt, warum Dicts in Python 3.6 weniger Speicher als Dicts in Python 2.7-3.5 verwenden. Es scheint jedoch einen Unterschied zwischen dem in Python 2.7 und 3.3-3.5 dicts verwendeten Speicher zu geben. Testcode:Warum verwendet Python2.7 dict mehr Speicherplatz als Python3 dict?

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

Als ich die Einsparungen zwischen 3,5 und 3,6 verstehen erwähnt, aber bin gespannt die Ursache für die Einsparungen zwischen 2,7 und 3,5.

+0

Hm, habe nie bemerkt, dieses, schöne Entdeckung. Ich bin mir nicht sicher, ob eine Änderung vorgenommen wurde, damit einfache Wörterbücher von der kombinierten Tabellenform profitieren können (siehe Fragen und Antworten, die ich hier gemacht habe (https://stackoverflow.com/questions/42419011/why-is-the-dict- of-instances-so-klein-in-python-3) auf Instanz dicts), aber es könnte sich lohnen, sie zu untersuchen. Ich bezweifle es aber :-) –

Antwort

9

Stellt sich heraus, dass dies ein Red Hering ist. Die Regeln zur Erhöhung der Dicts haben sich zwischen cPython 2.7 - 3.2 und cPython 3.3 und erneut bei cPython 3.4 geändert (obwohl diese Änderung nur bei Löschungen zutrifft). Wir können sehen, das den folgenden Code verwenden, um zu bestimmen, wenn die dict erweitert:

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 

Beachten Sie, dass dicts Größe ändern w Wenn sie 2/3 voll sind, können wir sehen, dass sich die cPython 2.7 dict-Implementierung bei der Erweiterung vervierfacht, während die cPython 3.5/3.6 dict-Implementierungen nur doppelt so groß sind.

Dies ist in der dict source code in einem Kommentar erklärt:

/* 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

Es wäre schön, wenn Raymond Hettinger diese Frage sieht und uns sagt, warum sie diese Änderung vorgenommen haben ... –

+0

@ PM2Ring Ich habe die [nächstbeste] (https: // www. youtube.com/watch?v=p33CVV29OG8&feature=youtu.be&t=21m57s) – Alex

Verwandte Themen