2008-09-25 10 views
13

उदाहरण के लिए, एक मिलियन (32-बिट) पूर्णांक की सूची को स्टोर करने के लिए कितनी मेमोरी आवश्यक है?पाइथन सूची (ट्यूपल) में प्रति तत्व कितने बाइट हैं?

alist = range(1000000) # or list(range(1000000)) in Python 3.0 
+0

इसका परीक्षण करें? मैंने बनाया ग्राफिकल उदाहरण: http://stackoverflow.com/a/30008338/2087463 – tmthydvnprt

+0

@tmthydvnprt: आपका उत्तर पूरी तरह से एक 'sys.getsizeof()' कॉल पर निर्भर करता है जो गलत है। परिणामों को मेरी प्रतिक्रिया से [asizeof.asizeof() 'के साथ तुलना करें] (http://stackoverflow.com/a/136083/4279) (उदाहरण के लिए, मेरे सिस्टम पर:' sys.getsizeof (रेंज (10 ** 6)) '->' 8000072' जबकि 'asizeof.asizeof (रेंज (10 ** 6))' -> '32000072')। – jfs

+0

एक 'sys.getsizeof()' गलत क्यों है? – tmthydvnprt

उत्तर

13

उपयोगी लिंक्स:

How to get memory size/usage of python object

Memory sizes of python objects?

if you put data into dictionary, how do we calculate the data size?

हालांकि वे एक निश्चित जवाब नहीं देते। जाने का तरीका:

  1. पायथन दुभाषिया द्वारा सूची के बिना/बिना सूची के ओपन मेमोरी को मापें (ओएस टूल्स का उपयोग करें)।

  2. किसी तृतीय-पक्ष एक्सटेंशन मॉड्यूल का उपयोग करें जो किसी प्रकार के आकार (PyObject) को परिभाषित करता है।

अद्यतन:

Recipe 546530: Size of Python objects (revised)

import asizeof 

N = 1000000 
print asizeof.asizeof(range(N))/N 
# -> 20 (python 2.5, WinXP, 32-bit Linux) 
# -> 33 (64-bit Linux) 
+0

क्या मैं सूची का आकार प्राप्त करने के लिए sys.getsizeof() का उपयोग कर सकता हूं? – Alcott

+1

@ एल्कोट: मॉड्यूल 'asizeof' उपलब्ध होने पर लागू होने पर' sys.getsizeof' का उपयोग करता है। – jfs

+0

अच्छी तरह से, asizeof एक तृतीय पक्ष सामान है, है ना? – Alcott

23

"यह निर्भर करता है।" पाइथन सूची में तत्वों को जोड़ने के लिए amortized constant time प्राप्त करने के लिए सूचियों के लिए स्थान आवंटित करता है।

प्रैक्टिस में, वर्तमान कार्यान्वयन के साथ इसका क्या अर्थ है ... सूची में हमेशा दो शक्तियों के लिए आवंटित स्थान होता है। तो रेंज (1000000) वास्तव में 2^20 तत्वों (~ 1.045 मिलियन) रखने के लिए काफी बड़ी सूची आवंटित करेगी।

यह केवल सूची संरचना को स्टोर करने के लिए आवश्यक स्थान है (जो प्रत्येक तत्व के लिए पायथन ऑब्जेक्ट्स के पॉइंटर्स की एक सरणी है)। एक 32-बिट सिस्टम को प्रति तत्व 4 बाइट्स की आवश्यकता होगी, एक 64-बिट सिस्टम प्रति तत्व 8 बाइट्स का उपयोग करेगा।

इसके अलावा, आपको वास्तविक तत्वों को संग्रहीत करने के लिए स्थान की आवश्यकता है। यह व्यापक रूप से भिन्न होता है। छोटे पूर्णांक (-5 से 256 वर्तमान में) के लिए, कोई अतिरिक्त स्थान की आवश्यकता नहीं है, लेकिन बड़ी संख्या के लिए पाइथन प्रत्येक पूर्णांक के लिए एक नई वस्तु आवंटित करता है, जो 10-100 बाइट लेता है और खंड स्मृति में जाता है।

निष्कर्ष: किसी यह जटिल है और अजगर सूचियों नहीं एक अच्छा तरीका बड़े सजातीय डेटा संरचनाओं स्टोर करने के लिए कर रहे हैं। इसके लिए, array मॉड्यूल का उपयोग करें या, यदि आपको वेक्टरकृत गणित करने की आवश्यकता है, तो NumPy का उपयोग करें।

पीएस-टुपल्स, सूचियों के विपरीत, डिज़ाइन नहीं किए गए हैं ताकि तत्वों को क्रमशः उनके साथ जोड़ा जा सके। मुझे नहीं पता कि आवंटक कैसे काम करता है, लेकिन बड़े डेटा संरचनाओं के लिए इसका उपयोग करने के बारे में भी सोचें :-)

+1

टुपल्स को अभी तक शामिल करने के लिए डिज़ाइन नहीं किया गया है, वे * को शामिल नहीं किया जा सकता है।निकटतम एनालॉग में एक नया ट्यूपल पूरी तरह से (और फिर संभावित रूप से पुराने को नष्ट करना) शामिल है जो बहुत अक्षम है। –

+0

हां वास्तव में। मुझे लगता है कि मुझे जो मिल रहा था वह है ... न केवल पाइथन टुपल्स में शामिल होने की इजाजत देता है, बल्कि आंतरिक रूप से उनके लिए स्मृति को इस तरह से कुशल बनाने के लिए प्रबंधित नहीं किया जाता है। –

+6

नाइटपिक: यह दो शक्ति विकास कारक नहीं है। यह आकार/8, प्लस 6 (या 3 अगर <= 8 आइटम) से अधिक आवंटित होता है, यह आकार के आनुपातिक है, इसलिए अभी भी निरंतर निरंतर जोड़ना होगा, लेकिन केवल ~ 12.5% ​​अतिरिक्त स्थान का उपयोग करेगा। कार्यान्वयन के लिए listobject.c देखें। – Brian

2

यह कार्यान्वयन विशिष्ट है, मुझे पूरा यकीन है। निश्चित रूप से यह पूर्णांक के आंतरिक प्रतिनिधित्व पर निर्भर करता है - आप यह नहीं मान सकते कि उन्हें 32-बिट के रूप में संग्रहीत किया जाएगा क्योंकि पाइथन आपको मनमाने ढंग से बड़े पूर्णांक देता है, इसलिए शायद छोटे स्याही अधिक कॉम्पैक्ट रूप से संग्रहीत किए जाते हैं।

मेरे पायथन (कोर 2 जोड़ी पर फेडोरा 9 पर 2.5.1) पर आवंटन से पहले VMSize 6896kB है, 22684 केबी के बाद। एक और मिलियन तत्व असाइनमेंट के बाद, VmSize 38340kB पर जाता है। यह बहुत ही 1000000 पूर्णांक के लिए लगभग 16000kB इंगित करता है, जो लगभग 16 बाइट प्रति पूर्णांक है। यह सूची के लिए ओवरहेड के लॉट का सुझाव देता है। मैं इन संख्याओं को नमक के एक बड़े चुटकी के साथ ले जाऊंगा।

6

को संबोधित करते "टपल" सवाल एक ठेठ निर्माण विन्यास में CPython के PyTuple की

घोषणा का हिस्सा इस करने पर निर्भर करता :

struct PyTuple { 
    size_t refcount; // tuple's reference count 
    typeobject *type; // tuple type object 
    size_t n_items; // number of items in tuple 
    PyObject *items[1]; // contains space for n_items elements 
}; 

PyTuple इंस्टेंस का आकार इसके निर्माण के दौरान तय किया गया है और बाद में बदला नहीं जा सकता है। PyTuple द्वारा कब्जे वाले बाइट्स की संख्या

sizeof(size_t) x 2 + sizeof(void*) x (n_items + 1) के रूप में गणना की जा सकती है।

यह टपल की उथले आकार देता है। पूर्ण आकार प्राप्त करने के लिए आपको PyTuple::items[] सरणी में रूट ऑब्जेक्ट ग्राफ़ द्वारा खपत बाइट्स की कुल संख्या जोड़ने की आवश्यकता है।

यह ध्यान देने योग्य है कि ट्यूपल निर्माण दिनचर्या सुनिश्चित करती है कि खाली टुपल का केवल एक उदाहरण कभी भी बनाया गया है (सिंगलटन)।

संदर्भ: Python.h, object.h, tupleobject.h, tupleobject.c

+1

से यह इतना आसान नहीं है, '() 32',' (1,) 48', '(1, 2) 72',' (1, 2, 3) 88' - आकार के आकार सहित आकार (पूर्णांक के लिए '16')। – jfs

+1

जोड़ा गया "उथले बनाम पूर्ण आकार" नोट। – Constantin

3

एक नया समारोह, getsizeof(), एक अजगर वस्तु राशि वस्तु द्वारा प्रयुक्त स्मृति की , बाइट में मापा लेता है और रिटर्न । बिल्ट-इन ऑब्जेक्ट्स सही परिणाम लौटाते हैं; तृतीय-पक्ष एक्सटेंशन नहीं हो सकते हैं, लेकिन ऑब्जेक्ट के आकार को वापस करने के लिए __sizeof__() विधि को परिभाषित कर सकते हैं।

[email protected]:~/py/r26rc2$ ./python 
Python 2.6rc2 (r26rc2:66712, Sep 2 2008, 13:11:55) 
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2 
>>> import sys 
>>> sys.getsizeof(range(1000000)) 
4000032 
>>> sys.getsizeof(tuple(range(1000000))) 
4000024 

जाहिर लौटे संख्याएं मौजूद वस्तुओं (sys.getsizeof (1) == 12) द्वारा खपत स्मृति शामिल नहीं हैं।

+0

मॉड्यूल 'asizeof' उपलब्ध होने पर लागू होने पर' sys.getsizeof' का उपयोग करता है। मेरा जवाब देखें – jfs

-1

मुझे डर है कि आप क्यों पूछ रहे हैं। क्या आप यह पता लगाने की कोशिश कर रहे हैं कि दिए गए कार्यान्वयन के लिए आपको कितनी मेमोरी चाहिए? कहें, आप 10,000,000 विजेट पढ़ने जा रहे हैं और जानना चाहते हैं कि यह कितनी रैम चूस जाएगी?

यदि यह पता लगाने की कोशिश करने के बजाय कि प्रत्येक विजेट कितना रैम लेता है, तो पता लगाएं कि कितना रैम, 10,000 विजेट लेता है और आपका वास्तविक आकार प्राप्त करने के लिए गुणा करता है।

+2

मुख्य अनुप्रयोग बैक-ऑफ-द-लिफाफा गणना है, जहां सामान्य ज्ञान होता है जब पाइथन नौकरी के लिए सही उपकरण होता है। – jfs

संबंधित मुद्दे