2010-01-22 32 views
19

Tôi ngạc nhiên rằng sys.getsizeof(10000*[x]) là 40036 bất kể x: 0, "a", 1000 * "a", {}.
Có một số deep_getsizeof xem xét đúng yếu tố chia sẻ bộ nhớ không?
(Câu hỏi đặt ra xuất phát từ nhìn vào bảng cơ sở dữ liệu trong bộ nhớ như phạm vi (1000000) -> tên tỉnh: danh sách hoặc dict?)
(Python là 2.6.4 trên ppc mac.)Python nhận được danh sách sâu với nội dung?

Added: 10000 * ["Mississippi"] là 10000 con trỏ đến một "Mississippi", như nhiều người đã chỉ ra. Hãy thử điều này:

nstates = [AlabamatoWyoming() for j in xrange(N)] 

nơi AlabamatoWyoming() -> một chuỗi "Alabama" .. "Wyoming". Deep_getsizeof (nstates) là gì?
(Làm thế nào chúng ta có thể nói

  • một deep_getsizeof thích: khó khăn, ~ gc tracer
  • ước tính từ tổng vm
  • bên trong kiến ​​thức về việc thực hiện trăn
  • đoán

. Đã thêm 25jan: cũng xem when-does-python-allocate-new-memory-for-identical-strings

Trả lời

5

Có một cái nhìn tại guppy/heapy; Tôi đã không chơi với nó quá nhiều bản thân mình, nhưng một vài đồng nghiệp của tôi đã sử dụng nó cho bộ nhớ hồ sơ với kết quả tốt.

Tài liệu có thể tốt hơn, nhưng this howto thực hiện công việc thích hợp để giải thích các khái niệm cơ bản.

+0

Cảm ơn Pär, sẽ thử nó; cho thấy khó khăn như thế nào. Bất kỳ đồng nghiệp nào của bạn có lưu ý ngắn về việc lưu bộ nhớ bằng Python, câu trả lời sẽ trả lời ví dụ: phạm vi (1000000) -> tên tỉnh: danh sách hoặc dict? – denis

+1

liên kết chết ở đó – MohamedEzz

14

10000 * [x] sẽ tạo danh sách 10000 lần cùng một đối tượng, vì vậy sizeof thực sự gần đúng hơn bạn nghĩ. Tuy nhiên, một sizeof sâu là rất có vấn đề bởi vì nó không thể nói với Python khi bạn muốn dừng phép đo. Mỗi đối tượng tham chiếu một typeobject. Nếu typeobject được tính? Điều gì xảy ra nếu tham chiếu đến typeobject là cái cuối cùng, vì vậy nếu bạn xóa đối tượng thì typeobject cũng sẽ biến mất? Điều gì về nếu bạn có nhiều đối tượng (khác nhau) trong danh sách tham chiếu đến cùng một đối tượng chuỗi? Nó có nên được tính một lần hay nhiều lần không?

Nói tóm lại, nhận được kích thước của một cấu trúc dữ liệu là rất phức tạp, và sys.getsizeof() nên không bao giờ đã được thêm vào: S

+0

+1 bạn phải xác định nơi dừng cho bất kỳ nội dung sâu nào. Bạn có muốn báo cáo bộ nhớ được chia sẻ bởi các phần khác của mã không? Sau đó, đó là gần như tất cả mọi thứ, vì nó có một tham chiếu đến 'đối tượng'. – nosklo

5

Nếu bạn danh sách chỉ giữ đối tượng với độ dài tương tự bạn có thể có được một số ước tính chính xác hơn bằng cách thực hiện điều này

def getSize(array): 
    return sys.getsizeof(array) + len(array) * sys.getsizeof(array[0]) 

Rõ ràng nó sẽ không hoạt động tốt cho các chuỗi có độ dài thay đổi.

Nếu bạn chỉ muốn tính kích thước để gỡ lỗi hoặc trong quá trình phát triển và bạn không quan tâm đến hiệu suất, bạn có thể lặp qua tất cả các mục đệ quy và tính tổng kích thước. Lưu ý rằng giải pháp này sẽ không xử lý nhiều tham chiếu đến cùng một đối tượng một cách chính xác.

0

mylist = 10000 * [x] có nghĩa là tạo danh sách kích thước 10000 với 10.000 tham chiếu đến đối tượng x.

Đối tượng xkhông được sao chép - chỉ một duy nhất tồn tại trong bộ nhớ !!!

Vì vậy, để sử dụng getsizeof, nó sẽ là: sys.getsizeof(mylist) + sys.getsizeof(x)

+0

Đó không phải là trường hợp cho các loại bất biến, sys.getsizeof (phạm vi (1000)) trả về cùng kích thước với sys.getsizeof ([0] * 1000) –

+0

@Nadia Alramli: Chính xác là điểm của tôi - cả hai ví dụ của bạn đang chạy 'sys. getizeof' trên danh sách 1000 mục - không quan trọng mục nào, vì vậy chúng sẽ trả về cùng kích thước. – nosklo

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