2013-06-05 36 views
5

Tôi có một số vấn đề liên quan đến một danh sách liên kết đơn giản Python và mức tiêu thụ bộ nhớ của nó.Phân bổ bộ nhớ kém trong Python LinkedList

Đây là mã:

import sys 

class Record: 
    def __init__(self,elem): 
     self.elem=elem 
     self.next=None 

    def size(self): 
     print 'elem.size = ', sys.getsizeof(self.elem) 
     print 'next.size = ', sys.getsizeof(self.next) 


class LinkedList: 
    def __init__(self): 
     self.first=None 
     self.last=None 

    def addAsLast(self,elem): 
     rec=Record(elem) 
     if self.first==None: 
      self.first=self.last=rec 
     else: 
      self.last.next=rec 
      self.last=rec 

if __name__=="__main__": 
    l=LinkedList() 
    r = Record(1) 
    r.size() 

    maxx = 10000000 
    r = range(1, maxx) 
    print 'size of r: ', sys.getsizeof(r) 
    print 'size of r[n-1]: ', sys.getsizeof(r[maxx-2]) 

    for i in r: 
     if(i% (maxx/10) == 0): print '.' 
     l.addAsLast(i) 
    print "The End" 

Vấn đề của tôi là thế này: chạy script này tiêu thụ 1,7 GB RAM tôi.

Output là:

elem.size = 12 
next.size = 8 
size of r: 40000028 
size of r[n-1]: 12 

như vậy, chúng ta hãy làm một số toán nhanh:

10 triệu Record.

Mỗi Ghi nhận 12 byte (elem) + 8 byte (con trỏ tới một kế tiếp) = 20 Bytes

20 byte * 10 triệu = 200.000.000 byte = 190,7 MB

Thậm chí nếu tôi phải xem xét danh sách được phân bổ bởi hàm range() (khoảng 30 MB) làm thế nào tôi có thể quản lý khoảng cách lớn về mức tiêu thụ bộ nhớ? Tôi đã thực hiện một số sai lầm ngu ngốc trong mã này? Tôi hy vọng câu trả lời sẽ khiến tôi cảm thấy xấu hổ và xin lỗi vì đã hỏi nó nhưng, tôi biết rằng, tôi đang tự hỏi điều gì đang xảy ra!

Cảm ơn trước sự giúp đỡ của bạn.

+2

Không phải là nó tạo nên khoảng trống lớn, nhưng bạn nên thay đổi phương thức '' 'size''' của' '' Record''' và làm cho nó in '' 'sys.sizeof (self)' '' thay thế của hai thành phần thành phần. Đó là 32 byte, không phải 20, bởi vì có chi phí trong cấu trúc lớp. –

+1

phân mảnh sẽ thêm một cái gì đó, tôi đoán. Tôi sẽ thử một cái gì đó như 'recpool = [None] * 10000000; ... rec = recpool [j]; j + = 1' và xem điều gì xảy ra. – Elazar

+1

cũng, hãy thử 'gc.disable()'. – Elazar

Trả lời

0
>>> class Record: 
...  def __init__(self, elem): 
...    self.elem = elem 
...    self.next = None 
... 
>>> r = Record(1) 
>>> sys.getsizeof(r) 
72 

Hoặc tôi có thiếu gì đó không?

Ngoài ra, trên hệ thống của tôi:

>>> sys.getsizeof(1) 
24 
>>> sys.getsizeof(None) 
16 
+0

là 56 trên máy của tôi – Elazar

+0

Suy nghĩ về nó ngay bây giờ : 56 hoặc 72 byte, nó vẫn không nên thêm tới 1,7 GB. Với 56 byte, toán đó có bạn ở ~ 600MB. Tôi sẽ tiếp tục suy nghĩ về nó :) – 2rs2ts

+0

56 + 28 = 84. làm tròn lên - 88. 88 * 10000000 ~ = 0.88GB. thêm phân mảnh và GC trên đầu, và bạn có một cái gì đó gần gũi. – Elazar

0

bị sửa đổi in-out như sau:

class Record: 
    def __init__(self,elem): 
     self.elem=elem 
     self.next=None 

    def size(self): 
     print 'Record size = ', sys.getsizeof(self) 
     print 'elem.size = ', sys.getsizeof(self.elem) 
     print 'next.size = ', sys.getsizeof(self.next) 

Output:

Record size = 72 
elem.size = 24 
next.size = 16 

Vì vậy, mỗi người trong số các nút danh sách liên kết của tôi là 72 byte x 10M phải là 720MB, .72GB

Tôi chạy chương trình, và sử dụng đầu, thấy rằng bộ nhớ trên là 3,6G. Kích thước elem của tôi gấp đôi kích thước của bạn và tôi nhận thấy gấp đôi tổng bộ nhớ được tiêu thụ như bạn (3.6G, so với 1.7G).

Điều này phải do phụ phí bộ nhớ trăn thừa, chẳng hạn như thu gom rác thải.

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