python - समवर - दो समान सूचियों में एक अलग मेमोरी फ़ुटप्रिंट क्यों होता है?




संघ सूची राज्यसूची एवं समवर्ती (2)

मैंने दो सूचियाँ l1 और l2 , लेकिन हर एक अलग निर्माण विधि के साथ:

import sys

l1 = [None] * 10
l2 = [None for _ in range(10)]

print('Size of l1 =', sys.getsizeof(l1))
print('Size of l2 =', sys.getsizeof(l2))

लेकिन आउटपुट ने मुझे चौंका दिया:

Size of l1 = 144
Size of l2 = 192

एक सूची समझ के साथ बनाई गई सूची स्मृति में एक बड़ा आकार है, लेकिन दो सूची पायथन में समान हैं अन्यथा।

ऐसा क्यों है? क्या यह कुछ सीपीथॉन की आंतरिक बात है, या कुछ अन्य स्पष्टीकरण है?


कोई भी स्मृति का एक खंड नहीं है, लेकिन यह पूर्व-निर्दिष्ट आकार नहीं है। उस के अलावा, सरणी तत्वों के बीच एक सरणी में कुछ अतिरिक्त रिक्ति है। आप इसे स्वयं चलाकर देख सकते हैं:

for ele in l2:
    print(sys.getsizeof(ele))

>>>>16
16
16
16
16
16
16
16
16
16

जो कि एल 2 के आकार का कुल नहीं है, बल्कि कम है।

print(sys.getsizeof([None]))
72

और यह l1 के आकार के दसवें हिस्से से बहुत अधिक है।

आपकी संख्या आपके ऑपरेटिंग सिस्टम के विवरण और आपके ऑपरेटिंग सिस्टम में वर्तमान मेमोरी उपयोग के विवरण के आधार पर अलग-अलग होनी चाहिए। [कोई नहीं] का आकार उपलब्ध आसन्न मेमोरी से कभी बड़ा नहीं हो सकता है जहां चर को संग्रहीत किया जाना है, और चर को स्थानांतरित करना पड़ सकता है यदि इसे बाद में गतिशील रूप से बड़ा होने के लिए आवंटित किया गया हो।


जब आप [None] * 10 लिखते हैं, तो पायथन को पता होता है कि उसे ठीक 10 वस्तुओं की सूची की आवश्यकता होगी, इसलिए यह बिल्कुल उसी को आवंटित करता है।

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

समान आकारों के साथ बनाई गई सूचियों की तुलना करते समय आप इस व्यवहार को देख सकते हैं:

>>> sys.getsizeof([None]*15)
184
>>> sys.getsizeof([None]*16)
192
>>> sys.getsizeof([None for _ in range(15)])
192
>>> sys.getsizeof([None for _ in range(16)])
192
>>> sys.getsizeof([None for _ in range(17)])
264

आप देख सकते हैं कि पहला तरीका सिर्फ उसी चीज को आवंटित करता है जो जरूरत है, जबकि दूसरा समय-समय पर बढ़ता है। इस उदाहरण में, यह 16 तत्वों के लिए पर्याप्त आवंटित करता है, और 17 वें तक पहुंचने पर इसे फिर से प्राप्त करना पड़ता है।





python-internals