2017-07-24 17 views
6

Tôi đã đọc khoảng Raymond Hettinger's new method triển khai compact dicts. Điều này giải thích tại sao dicts trong Python 3.6 sử dụng ít bộ nhớ hơn dicts trong Python 2.7-3.5. Tuy nhiên dường như có sự khác biệt giữa bộ nhớ được sử dụng trong Python 2.7 và 3.3-3.5 dicts. mã kiểm tra:Tại sao Python2.7 dict sử dụng nhiều không gian hơn 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

Như đã đề cập tôi hiểu các khoản tiết kiệm giữa 3.5 và 3.6 nhưng tò mò về nguyên nhân của khoản tiết kiệm giữa 2,7 và 3,5.

+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ù :-) –

Trả lời

9

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

Sẽ thật tuyệt nếu Raymond Hettinger thấy câu hỏi này và cho chúng tôi biết tại sao họ thực hiện thay đổi đó ... –

+0

@ PM2Ring Tôi có [điều tốt nhất tiếp theo] (https: // www. youtube.com/watch?v=p33CVV29OG8&feature=youtu.be&t=21m57s) – Alex

Các vấn đề liên quan