Hóa ra đây là cá trích đỏ. Các quy tắc để tăng kích thước của dicts thay đổi giữa cPython 2.7 - 3.2 và cPython 3.3 và một lần nữa tại cPython 3.4 (mặc dù thay đổi này chỉ áp dụng khi việc xóa xảy ra). Chúng ta có thể thấy điều này bằng cách sử dụng đoạn mã sau để xác định khi dict mở rộng:
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
Lưu ý rằng dicts thay đổi kích thước w hen họ nhận được là 2/3 đầy đủ, chúng ta có thể thấy rằng cPython 2.7 dict thực hiện quadruples kích thước khi nó mở rộng trong khi cPython 3.5/3.6 dict triển khai chỉ tăng gấp đôi kích thước.
này được giải thích trong một chú thích trong 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
*/
Hm, không bao giờ nhận thấy điều này, đẹp find. Tôi không chắc chắn nếu một sự thay đổi đã được thực hiện để từ điển đơn giản có thể được hưởng lợi từ hình thức bảng kết hợp (xem một Q & A tôi đã làm ở đây] (https://stackoverflow.com/questions/42419011/why-is-the-dict- of-instances-so-small-in-python-3) trên các dicts ví dụ) nhưng có thể đáng để nghiên cứu nó. Tôi nghi ngờ nó mặc dù :-) –