Hướng dẫn dictionary vs list memory usage python - từ điển so với danh sách sử dụng bộ nhớ python

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

Hướng dẫn dictionary vs list memory usage python - từ điển so với danh sách sử dụng bộ nhớ python

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.

Từ điển Python có chiếm rất nhiều bộ nhớ không?

Nói cách khác, từ điển của chúng tôi, không có gì trong đó, tiêu thụ 240 byte.Không tệ;Với tần suất từ điển được sử dụng trong Python, thật tốt khi biết rằng chúng thường không tiêu thụ nhiều bộ nhớ đó.they don't normally consume that much memory.

Từ điển có nhanh hơn danh sách Python không?

Một từ điển nhanh hơn 6,6 lần so với danh sách khi chúng tôi tra cứu trong 100 mục.6.6 times faster than a list when we lookup in 100 items.

Tại sao Dict nhanh hơn danh sách?

Lý do là vì một từ điển là một tra cứu, trong khi một danh sách là một lần lặp.Từ điển sử dụng tra cứu băm, trong khi danh sách của bạn yêu cầu đi bộ qua danh sách cho đến khi tìm thấy kết quả từ việc bắt đầu đến kết quả mỗi lần.a dictionary is a lookup, while a list is an iteration. Dictionary uses a hash lookup, while your list requires walking through the list until it finds the result from beginning to the result each time.

Bao nhiêu bộ nhớ mà một danh sách mất trong Python?

Khi bạn tạo một đối tượng Danh sách, đối tượng danh sách tự mình lấy 64 byte bộ nhớ và mỗi mục thêm 8 byte bộ nhớ vào kích thước của danh sách vì các tham chiếu đến các đối tượng khác.64 bytes of memory, and each item adds 8 bytes of memory to the size of the list because of references to other objects.