Bạn thực sự nhận được một hình ảnh không hoàn chỉnh về việc sử dụng bộ nhớ trong trường hợp này. Tổng kích thước của một từ điển nhiều hơn gấp đôi trong các khoảng thời gian không đều và nếu bạn so sánh kích thước của hai cấu trúc này ngay sau khi kích thước từ điển đã tăng lên, nó lại lớn hơn. Một tập lệnh đơn giản với hàm kích thước đệ quy [xem mã bên dưới] hiển thị một mẫu khá rõ ràng:
i: 2 list size: 296 dict size: 328 difference: -32
i: 3 list size: 392 dict size: 352 difference: 40
i: 4 list size: 488 dict size: 376 difference: 112
i: 5 list size: 616 dict size: 400 difference: 216
i: 7 list size: 808 dict size: 1216 difference: -408
i: 10 list size: 1160 dict size: 1288 difference: -128
i: 13 list size: 1448 dict size: 1360 difference: 88
i: 17 list size: 1904 dict size: 1456 difference: 448
i: 23 list size: 2480 dict size: 3904 difference: -1424
i: 31 list size: 3328 dict size: 4096 difference: -768
i: 42 list size: 4472 dict size: 4360 difference: 112
i: 56 list size: 5912 dict size: 4696 difference: 1216
i: 74 list size: 7880 dict size: 5128 difference: 2752
i: 100 list size: 10520 dict size: 14968 difference: -4448
i: 133 list size: 14024 dict size: 15760 difference: -1736
i: 177 list size: 18672 dict size: 16816 difference: 1856
Mô hình này tiếp tục khi i
phát triển. . Hủy bỏ lợi thế bộ nhớ của danh sách trên từ điển. Nhưng kết quả, trung bình, không phải là từ điển tốt hơn; Đó là từ điển giống nhau. Vì vậy, để trả lời cho câu hỏi ban đầu của bạn:
Khi bạn muốn lưu trữ nhiều dữ liệu giá trị khóa trong bộ nhớ, cấu trúc dữ liệu nào tiết kiệm bộ nhớ hơn, một dict hoặc một danh sách các bộ dữ liệu?
Nó không thực sự quan trọng nếu tất cả những gì bạn quan tâm là bộ nhớ.
Tuy nhiên, lưu ý rằng việc lặp lại trên một từ điển thường chậm hơn một chút so với lặp lại trong danh sách, bởi vì không có cách nào tốt để tránh lặp đi lặp lại trên tất cả các thùng rỗng trong từ điển. Vì vậy, có một chút sự đánh đổi - từ điển nhanh hơn [nhiều] trong việc tìm kiếm chính ngẫu nhiên, nhưng danh sách [một chút] nhanh hơn khi lặp. Từ điển có thể sẽ tốt hơn hầu hết thời gian, nhưng trong một số trường hợp hiếm hoi, danh sách có thể cung cấp tối ưu hóa vi mô.
Đây là mã kiểm tra kích thước. Nó có thể sẽ không tạo ra kết quả chính xác cho tất cả các trường hợp góc, nhưng nó nên xử lý các cấu trúc đơn giản như thế này mà không gặp vấn đề gì. [Nhưng hãy cho tôi biết nếu bạn thấy bất kỳ vấn đề nào.]
import sys, collections, itertools, math
def totalsize[x]:
seen = set[]
return ts_rec[x, seen]
def ts_rec[x, seen]:
if id[x] in seen:
return 0
else:
seen.add[id[x]]
x_size = sys.getsizeof[x]
if isinstance[x, collections.Mapping]:
kv_chain = itertools.chain.from_iterable[x.iteritems[]]
return x_size + sum[ts_rec[i, seen] for i in kv_chain]
elif isinstance[x, collections.Sequence]:
return x_size + sum[ts_rec[i, seen] for i in x]
else:
return x_size
for i in [10 ** [e / 8.0] for e in range[3, 19]]:
i = int[i]
lsize = totalsize[[[x, x] for x in xrange[i]]]
dsize = totalsize[dict[[x, x] for x in xrange[i]]]
print "i: ", i,
print " list size: ", lsize, " dict size: ", dsize,
print " difference: ", lsize - dsize
Giới thiệu
Trong bài đăng này, chúng tôi muốn đánh giá dấu chân bộ nhớ trong Python 3 của dữ liệu được lưu trữ ở các định dạng dạng bảng khác nhau. Cụ thể, chúng tôi muốn so sánh các khung dữ liệu, với các cấu trúc dữ liệu giống JSON như danh sách từ điển và từ điển của danh sách.
Trên đây là 3 cách khác nhau để lưu trữ dữ liệu giống như bảng. Dữ liệu giống như bảng về cơ bản là dữ liệu được biểu thị bằng các hàng và cột. Trong bài kiểm tra này, chúng tôi sẽ bỏ qua bất kỳ câu hỏi nào liên quan đến đọc/ghi hiệu quả hoặc tra cứu. Chúng tôi hoàn toàn quan tâm đến một câu hỏi: cách tiếp cận nào sẽ giúp chúng tôi tiết kiệm nhiều trí nhớ nhất?
Bộ dữ liệu
Chúng tôi tạo ra một bộ dữ liệu thử nghiệm vô nghĩa [nhưng rất lớn] cho thí nghiệm này, sử dụng danh sách một số giống chó phổ biến. Danh sách này chắc chắn hoàn toàn không thiên vị, và tất cả chúng chắc chắn là những con chó.
Để đảm bảo rằng thử nghiệm đủ chung cho hầu hết các trường hợp sử dụng, chúng tôi đảm bảo rằng bộ dữ liệu này có ít nhất ba loại dữ liệu nguyên thủy: STR, INT và FLOAT.
Thí nghiệm
Chúng tôi chạy các tính toán đơn giản cho từng biến thể cấu trúc dữ liệu.
DataFrames
Đo lường bộ nhớ của DataFrames tương đối đơn giản và có thể được thực hiện với chức năng tích hợp đơn giản: DataFrame.memory_usage
.
Điều này cho kết quả sau:
Danh sách từ điển
Đo lường danh sách từ điển không đơn giản như ở trên.
Để có được kích thước của cấu trúc dữ liệu Python bản địa, chúng ta có thể sử dụng phương pháp sys.getsizeof
. Tuy nhiên, điều này chỉ cung cấp cho chúng ta kích thước [tính bằng byte] của chính đối tượng, mà không bao gồm kích thước của các phần tử lồng nhau.
Ví dụ: nếu một người có một danh sách các số nguyên [1, 2, 3]
, hãy gọi sys.getsizeof[[1, 2, 3]]
sẽ chỉ trả về kích thước của danh sách trống rỗng, cùng với bộ nhớ được phân bổ. Kích thước này sẽ không bao gồm các số nguyên 1, 2 hoặc 3. Bạn có thể thực hiện một vấn đề sâu sắc về vấn đề này trên câu hỏi Overflow Stack Stack rất nhiều thông tin này.
Do đó, người ta phải lặp lại từng đối tượng trong danh sách và mỗi cặp giá trị khóa trong mỗi từ điển để có được kích thước tích lũy của cấu trúc dữ liệu.
Điều này cho kết quả sau:
Danh sách từ điển
Đo lường danh sách từ điển không đơn giản như ở trên.
Để có được kích thước của cấu trúc dữ liệu Python bản địa, chúng ta có thể sử dụng phương pháp sys.getsizeof
. Tuy nhiên, điều này chỉ cung cấp cho chúng ta kích thước [tính bằng byte] của chính đối tượng, mà không bao gồm kích thước của các phần tử lồng nhau.
{
"breed": [ ... ],
"count": [ ... ],
"barks": [ ... ],
}
Ví dụ: nếu một người có một danh sách các số nguyên [1, 2, 3]
, hãy gọi sys.getsizeof[[1, 2, 3]]
sẽ chỉ trả về kích thước của danh sách trống rỗng, cùng với bộ nhớ được phân bổ. Kích thước này sẽ không bao gồm các số nguyên 1, 2 hoặc 3. Bạn có thể thực hiện một vấn đề sâu sắc về vấn đề này trên câu hỏi Overflow Stack Stack rất nhiều thông tin này.
Điều này cho kết quả sau:
Danh sách từ điển
Đo lường danh sách từ điển không đơn giản như ở trên.significantly smaller footprint than a list of dictionaries, and even a dictionary of lists. The latter are roughly 6 times and 2 times larger, respectively.
Để có được kích thước của cấu trúc dữ liệu Python bản địa, chúng ta có thể sử dụng phương pháp sys.getsizeof
. Tuy nhiên, điều này chỉ cung cấp cho chúng ta kích thước [tính bằng byte] của chính đối tượng, mà không bao gồm kích thước của các phần tử lồng nhau.