2012-11-23 27 views
22

我一直在尋找一種簡單的方法來知道數組和字典對象的字節大小,就像如何知道像數組和字典這樣的python對象的字節大小? - 最簡單的方法

[ [1,2,3], [4,5,6] ] or { 1:{2:2} } 

很多話題說使用pylab,例如:

from pylab import * 

A = array([ [1,2,3], [4,5,6] ]) 
A.nbytes 
24 

但是,字典呢? 我看到很多提議使用pysize或heapy的答案。 Torsten Marek在這個鏈接中給出了一個簡單的答案:Which Python memory profiler is recommended?,但是由於字節數不匹配,我對輸出沒有一個明確的解釋。

Pysize似乎更加複雜,我沒有關於如何尚未使用它一個明確的想法。

鑑於大小計算,我想執行關於簡單的方法來獲得這種對象的內存使用量的近似估計(不上課,也沒有複雜的結構),任何想法的簡單?

親切的問候。

回答

31

有:

>>> import sys 
>>> sys.getsizeof([1,2, 3]) 
96 
>>> a = [] 
>>> sys.getsizeof(a) 
72 
>>> a = [1] 
>>> sys.getsizeof(a) 
80 

但我不會說這是可靠的,因爲Python有開銷爲每個對象,並有包含什麼,但對其他對象引用的對象,所以它不是完全一樣如在C和其他語言中一樣。

sys.getsizeof的文檔的讀取,並從那裏我猜去。

+0

我試過這種方式,但是當你試圖得到一個列表的列表的大小,你得到的只是父列表中的大小,而不是與嵌套表總。 我不知道如果我編寫代碼來做遞歸,我會得到真正的內存使用。 – crandrades

+3

@ user1847706在條目結尾處我將文檔鏈接到文檔中,有[請參閱recursive sizeof recipe以遞歸方式使用getsizeof()來查找容器及其所有內容大小的示例。](http:// code .activestate.com/recipes/577504 /) –

+0

感謝您的回答。現在,我試圖添加一個處理程序來計算用戶定義的類的內存使用情況。 – crandrades

19

晚了一點,但一個簡單的方法來得到字典的大小是先泡菜吧。

使用Python對象(包括字典)上sys.getsizeof可能不準確,因爲它不計數引用的對象。

來處理它的方式是把它序列化到一個字符串和字符串sys.getsizeof使用。結果將更接近你想要的。

import cPickle 

mydict = {'key1':'some long string, 'key2':[some, list], 'key3': whatever other data} 

做sys.getsizeof(mydict)是不準確的話,鹹菜首先

mydict_as_string = cPickle.dumps(mydict) 

現在我們可以知道它佔用多少空間由

print sys.getsizeof(mydict_as_string) 
+3

這不會告訴你字典的大小;它會告訴你字典的pickle表示的大小,它將比dict的內存大小更大(可能相當大)。 – jbg

+0

@ JasperBryant-Greene這就是要點。在Python對象(包括字典)上使用sys.getsizeof可能不準確,因爲它不計算引用對象。對它進行序列化,然後獲得大小並不確切,但會更接近你想要的。將其視爲近似值。 –

+0

當然,但問題要求「這種對象的內存使用情況的近似估計」。我認爲這甚至沒有資格作爲對內存使用量的估計 - 醃漬的尺寸通常會更大。 – jbg

7

使用這個配方,取自:

http://code.activestate.com/recipes/577504-compute-memory-footprint-of-an-object-and-its-cont/

from __future__ import print_function 
from sys import getsizeof, stderr 
from itertools import chain 
from collections import deque 
try: 
    from reprlib import repr 
except ImportError: 
    pass 

def total_size(o, handlers={}, verbose=False): 
    """ Returns the approximate memory footprint an object and all of its contents. 

    Automatically finds the contents of the following builtin containers and 
    their subclasses: tuple, list, deque, dict, set and frozenset. 
    To search other containers, add handlers to iterate over their contents: 

     handlers = {SomeContainerClass: iter, 
        OtherContainerClass: OtherContainerClass.get_elements} 

    """ 
    dict_handler = lambda d: chain.from_iterable(d.items()) 
    all_handlers = {tuple: iter, 
        list: iter, 
        deque: iter, 
        dict: dict_handler, 
        set: iter, 
        frozenset: iter, 
        } 
    all_handlers.update(handlers)  # user handlers take precedence 
    seen = set()      # track which object id's have already been seen 
    default_size = getsizeof(0)  # estimate sizeof object without __sizeof__ 

    def sizeof(o): 
     if id(o) in seen:  # do not double count the same object 
      return 0 
     seen.add(id(o)) 
     s = getsizeof(o, default_size) 

     if verbose: 
      print(s, type(o), repr(o), file=stderr) 

     for typ, handler in all_handlers.items(): 
      if isinstance(o, typ): 
       s += sum(map(sizeof, handler(o))) 
       break 
     return s 

    return sizeof(o) 


##### Example call ##### 

if __name__ == '__main__': 
    d = dict(a=1, b=2, c=3, d=[4,5,6,7], e='a string of chars') 
    print(total_size(d, verbose=True)) 
相關問題