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
*/
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 :-) –