python - मैं पायथन में किसी ऑब्जेक्ट का आकार कैसे निर्धारित करूं?




object memory (6)

सी में, हम एक int , char , आदि का आकार पा सकते हैं। मैं जानना चाहता हूं कि पाइथन में स्ट्रिंग, इंटीजर इत्यादि जैसी वस्तुओं का आकार कैसे प्राप्त करें।

संबंधित प्रश्न: पाइथन सूची (ट्यूपल) में प्रति तत्व कितने बाइट हैं?

मैं एक एक्सएमएल फ़ाइल का उपयोग कर रहा हूं जिसमें आकार फ़ील्ड शामिल हैं जो मान के आकार को निर्दिष्ट करते हैं। मुझे इस एक्सएमएल को पार्स करना होगा और मेरा कोडिंग करना होगा। जब मैं किसी विशेष फ़ील्ड के मान को बदलना चाहता हूं, तो मैं उस मान के आकार फ़ील्ड की जांच करूंगा। यहां मैं तुलना करना चाहता हूं कि नया मान जो मैं दर्ज करने के लिए गोंग हूं, एक्सएमएल में समान आकार का है। मुझे नए मूल्य के आकार की जांच करने की जरूरत है। एक स्ट्रिंग के मामले में मैं इसकी लंबाई कह सकता हूं। लेकिन int, float, आदि के मामले में मैं उलझन में हूँ।


मैं पायथन में किसी ऑब्जेक्ट का आकार कैसे निर्धारित करूं?

जवाब, "बस sys.getsizeof का उपयोग करें" एक पूर्ण उत्तर नहीं है।

वह उत्तर सीधे निर्मित वस्तुओं के लिए काम करता है , लेकिन यह उन वस्तुओं के लिए जिम्मेदार नहीं है, विशेष रूप से, किस प्रकार, जैसे टुपल्स, सूचियां, डाइक और सेट शामिल हैं। उनमें एक-दूसरे के साथ-साथ संख्याएं, तार और अन्य वस्तुएं भी शामिल हो सकती हैं।

एक और पूरा जवाब

guppy.hpy के साथ एनाकोंडा वितरण और guppy.hpy से 64 बिट पायथन 2.7 का उपयोग करके, मैंने निम्न ऑब्जेक्ट्स का न्यूनतम आकार निर्धारित किया है, और ध्यान दें कि सेट्स और sys.getsizeof को sys.getsizeof करते हैं ताकि रिक्त स्थान सेट के बाद तक फिर से न बढ़ें राशि (जो भाषा के कार्यान्वयन से भिन्न हो सकती है):

Bytes  type        empty + scaling notes
24     int         NA
28     long        NA
37     str         + 1 byte per additional character
52     unicode     + 4 bytes per additional character
56     tuple       + 8 bytes per additional item
72     list        + 32 for first, 8 for each additional
232    set         sixth item increases to 744; 22nd, 2280; 86th, 8424
280    dict        sixth item increases to 1048; 22nd, 3352; 86th, 12568 *
64     class inst  has a __dict__ attr, same scaling as dict above
16     __slots__   class with slots has no dict, seems to store in 
                   mutable tuple-like structure.
120    func def    doesn't include default args and other attrs
904    class def   has a proxy __dict__ structure for class attrs
104    old class   makes sense, less stuff, has real dict though.

* ध्यान दें कि शब्दकोश ( लेकिन सेट नहीं ) पाइथन 3.6 में अधिक कॉम्पैक्ट प्रतिनिधित्व प्राप्त कर रहे हैं

मुझे लगता है कि संदर्भ के लिए प्रति अतिरिक्त 8 बाइट 64 बिट मशीन पर बहुत अधिक समझ में आता है। उन 8 बाइट्स स्मृति में जगह पर इंगित करते हैं जिसमें निहित वस्तु है। यदि मैं सही ढंग से याद करता हूं, तो पाइथन 2 में यूनिकोड के लिए 4 बाइट निश्चित चौड़ाई हैं, लेकिन पायथन 3 में, स्ट्र वर्णों की अधिकतम चौड़ाई के बराबर चौड़ाई का यूनिकोड बन जाता है।

(और स्लॉट पर अधिक के लिए, यह जवाब देखें )

एक अधिक पूर्ण समारोह के लिए रिकर्सिव विज़िटर

इन प्रकारों में से अधिकांश को कवर करने के लिए, मैंने अधिकांश पायथन ऑब्जेक्ट्स के आकार का अनुमान लगाने के लिए इस रिकर्सिव फ़ंक्शन को लिखा है, जिसमें अधिकांश बिल्टिन, संग्रह मॉड्यूल में प्रकार और कस्टम प्रकार (स्लॉट और अन्यथा) शामिल हैं:

import sys
from numbers import Number
from collections import Set, Mapping, deque

try: # Python 2
    zero_depth_bases = (basestring, Number, xrange, bytearray)
    iteritems = 'iteritems'
except NameError: # Python 3
    zero_depth_bases = (str, bytes, Number, range, bytearray)
    iteritems = 'items'

def getsize(obj_0):
    """Recursively iterate to sum size of object & members."""
    def inner(obj, _seen_ids = set()):
        obj_id = id(obj)
        if obj_id in _seen_ids:
            return 0
        _seen_ids.add(obj_id)
        size = sys.getsizeof(obj)
        if isinstance(obj, zero_depth_bases):
            pass # bypass remaining control flow and return
        elif isinstance(obj, (tuple, list, Set, deque)):
            size += sum(inner(i) for i in obj)
        elif isinstance(obj, Mapping) or hasattr(obj, iteritems):
            size += sum(inner(k) + inner(v) for k, v in getattr(obj, iteritems)())
        # Check for custom object instances - may subclass above too
        if hasattr(obj, '__dict__'):
            size += inner(vars(obj))
        if hasattr(obj, '__slots__'): # can have __slots__ with __dict__
            size += sum(inner(getattr(obj, s)) for s in obj.__slots__ if hasattr(obj, s))
        return size
    return inner(obj_0)

और मैंने इसे आकस्मिक रूप से परीक्षण किया (मुझे इसे एकजुट करना चाहिए):

>>> getsize(['a', tuple('bcd'), Foo()])
344
>>> getsize(Foo())
16
>>> getsize(tuple('bcd'))
194
>>> getsize(['a', tuple('bcd'), Foo(), {'foo': 'bar', 'baz': 'bar'}])
752
>>> getsize({'foo': 'bar', 'baz': 'bar'})
400
>>> getsize({})
280
>>> getsize({'foo':'bar'})
360
>>> getsize('foo')
40
>>> class Bar():
...     def baz():
...         pass
>>> getsize(Bar())
352
>>> getsize(Bar().__dict__)
280
>>> sys.getsizeof(Bar())
72
>>> getsize(Bar.__dict__)
872
>>> sys.getsizeof(Bar.__dict__)
280

यह वर्ग परिभाषाओं और कार्य परिभाषाओं पर टूट जाता है क्योंकि मैं उनके सभी गुणों के बाद नहीं जाता हूं, लेकिन चूंकि उन्हें प्रक्रिया के लिए स्मृति में केवल एक बार मौजूद होना चाहिए, इसलिए उनका आकार वास्तव में बहुत अधिक मायने रखता नहीं है।


Numpy arrays के लिए, getsizeof काम नहीं करता है - मेरे लिए यह हमेशा किसी कारण से 40 देता है:

from pylab import *
from sys import getsizeof
A = rand(10)
B = rand(10000)

फिर (ipython में):

In [64]: getsizeof(A)
Out[64]: 40

In [65]: getsizeof(B)
Out[65]: 40

खुशी से, यद्यपि:

In [66]: A.nbytes
Out[66]: 80

In [67]: B.nbytes
Out[67]: 80000

पहला: एक उत्तर।

import sys

try: print sys.getsizeof(object)
except AttributeError:
    print "sys.getsizeof exists in Python ≥2.6"

चर्चा:
पायथन में, आप कभी भी "प्रत्यक्ष" स्मृति पते तक नहीं पहुंच सकते हैं। फिर, आपको यह जानना होगा कि किसी दिए गए ऑब्जेक्ट द्वारा कितने पते पर कब्जा किया गया है ?? यह एक सवाल है जो अमूर्तता के उस स्तर पर पूरी तरह अनुचित है। जब आप अपने घर को चित्रित कर रहे हैं, तो आप नहीं पूछते कि पेंट के भीतर प्रत्येक घटक परमाणुओं द्वारा प्रकाश की आवृत्तियों को अवशोषित या प्रतिबिंबित किया जाता है, आप बस पूछें कि यह किस रंग का है - भौतिक विशेषताओं का विवरण जो उस रंग को बनाता है बिंदु के बगल में हैं। इसी तरह, स्मृति के बाइट्स की संख्या जो दी गई पाइथन ऑब्जेक्ट पर निर्भर करती है वह बिंदु के बगल में है।

तो, आप सी कोड लिखने के लिए पायथन का उपयोग क्यों कर रहे हैं? :)


यदि कोई इस प्रश्न पर आता है और sys.getsizeof या हारून हॉल द्वारा प्रदान की गई प्रक्रिया की तुलना में अधिक "बुलेटप्रूफ" समाधान की आवश्यकता है, तो here एक नुस्खा here जो कक्षाओं और बाइटकोड वस्तुओं जैसे मुद्दों को एक सिद्धांतबद्ध और लचीला तरीके से निपटने का प्रयास करता है (दुर्भाग्यवश यहां दोहराना या अर्थपूर्ण रूप से सारांशित करना बहुत लंबा है)।


यहां एक त्वरित लिपि है जिसे मैंने पिछले चर के सभी आकारों के सूची के पिछले उत्तरों के आधार पर लिखा था

for i in dir():
    print (i, sys.getsizeof(eval(i)) )

Pympler पैकेज के asizeof मॉड्यूल यह कर सकते हैं।

निम्नानुसार उपयोग करें:

from pympler import asizeof
asizeof.asizeof(my_object)

sys.getsizeof विपरीत, यह आपके स्वयं निर्मित वस्तुओं के लिए काम करता है । यह भी numpy के साथ काम करता है।

>>> asizeof.asizeof(tuple('bcd'))
200
>>> asizeof.asizeof({'foo': 'bar', 'baz': 'bar'})
400
>>> asizeof.asizeof({})
280
>>> asizeof.asizeof({'foo':'bar'})
360
>>> asizeof.asizeof('foo')
40
>>> asizeof.asizeof(Bar())
352
>>> asizeof.asizeof(Bar().__dict__)
280
>>> A = rand(10)
>>> B = rand(10000)
>>> asizeof.asizeof(A)
176
>>> asizeof.asizeof(B)
80096

जैसा कि mentioned ,

कक्षाओं, कार्यों, विधियों, मॉड्यूल इत्यादि जैसी वस्तुओं के (बाइट) कोड आकार को विकल्प code=True सेट करके शामिल किया जा सकता है।

और यदि आपको लाइव डेटा, Pympler पर अन्य दृश्य की आवश्यकता है

मॉड्यूल muppy का उपयोग एक पायथन अनुप्रयोग और मॉड्यूल Class Tracker की ऑनलाइन निगरानी के लिए किया जाता है चयनित पायथन ऑब्जेक्ट्स के जीवनकाल का ऑफ-लाइन विश्लेषण प्रदान करता है।





sizeof