2012-11-23 8 views
22

मैं सरणियों और शब्दकोशों वस्तु की बाइट आकार पता करने के लिए एक आसान तरीका के लिए देख रहा था,एरे और शब्दकोश जैसे पायथन ऑब्जेक्ट के बाइट्स आकार को कैसे जानें? - आसान तरीका

तरह
[ [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 

लेकिन, शब्दकोश के बारे में क्या? मैंने पाइज़ या हेपी का उपयोग करने का प्रस्ताव देने वाले कई उत्तरों को देखा। इस लिंक में टोरस्टन मरेक द्वारा एक आसान उत्तर दिया गया है: 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 

लेकिन मैं इसे, कि विश्वसनीय के रूप में अजगर प्रत्येक वस्तु के लिए भूमि के ऊपर है नहीं कह सकते हैं कि, और वहाँ वस्तुओं है कि लेकिन अन्य वस्तुओं के लिए संदर्भ में कुछ भी नहीं होते हैं, तो यह काफी एक ही नहीं है सी और अन्य भाषाओं में के रूप में।

sys.getsizeof पर डॉक्स का एक पढ़ा है और मुझे लगता है कि वहाँ से चलते हैं।

+0

मुझे लगता है कि जिस तरह से कोशिश की, लेकिन जब आप सूचियों की एक सूची के आकार प्राप्त करने की कोशिश, आप केवल माता-पिता सूची आकार और नेस्ट सूचियों के साथ कुल नहीं मिलता है। मुझे नहीं पता कि मैं रिकर्सन करने के लिए कोड लिखता हूं, मुझे वास्तविक स्मृति उपयोग मिल जाएगा। प्रविष्टि के अंत में – crandrades

+3

@ user1847706 मैंने आपको दस्तावेज़ों में लिंक किया है, वहां है [कंटेनरों के आकार और उनकी सभी सामग्री को ढूंढने के लिए पुनरावर्ती रूप से getizeof() का उपयोग करने के उदाहरण के लिए रिकर्सिव आकार का नुस्खा देखें।] (Http: // कोड .activestate.com/व्यंजनों/577504 /) –

+0

आपके उत्तर के लिए धन्यवाद। अब, मैं उपयोगकर्ता परिभाषित वर्ग के लिए स्मृति उपयोग की गणना करने के लिए एक हैंडलर जोड़ने की कोशिश कर रहा हूं। – crandrades

19

पार्टी लेकिन dict के आकार पाने के लिए एक आसान तरीका करने के लिए देर से थोड़ा पहले यह अचार है।

(शब्दकोश सहित) अजगर वस्तु पर 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

यह आपको निर्देश का आकार नहीं बताएगा; यह आपको ताना के अचार के आकार की तुलना में बताएगा, जो कि बड़े पैमाने पर (संभावित रूप से काफी मात्रा में) होगा। – jbg

+0

@ जैस्पर ब्रायंट-ग्रीन जो बिंदु है। पायथन ऑब्जेक्ट (शब्दकोश समेत) पर 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)) 
संबंधित मुद्दे