python - पायथन में बड़े पूर्णांक के लिए स्मृति आवंटन को समझना
python-3.x int (2)
पाइथन बड़े पूर्णांक के लिए स्मृति आवंटित कैसे करता है?
एक int
प्रकार में 28 bytes
का आकार होता है और जैसे ही मैं int
के मान को बढ़ाता रहता हूं, आकार 4 bytes
की वृद्धि में बढ़ता है।
शुरुआत में
28 bytes
किसी भी मूल्य के लिए1
रूप में कम क्यों?4 bytes
की वृद्धि क्यों?
पीएस: मैं एक x86_64 (64 बिट मशीन) पर पायथन 3.5.2 चला रहा हूँ। इस तरह की बड़ी संख्याओं पर (3.0+) दुभाषिया कैसे काम करते हैं, इस पर कोई पॉइंटर्स / संसाधन / पीईपी है जो मैं ढूंढ रहा हूं।
आकार को चित्रित कोड:
>>> a=1
>>> print(a.__sizeof__())
28
>>> a=1024
>>> print(a.__sizeof__())
28
>>> a=1024*1024*1024
>>> print(a.__sizeof__())
32
>>> a=1024*1024*1024*1024
>>> print(a.__sizeof__())
32
>>> a=1024*1024*1024*1024*1024*1024
>>> a
1152921504606846976
>>> print(a.__sizeof__())
36
शुरुआत में
28
बाइट्स किसी भी मूल्य के लिए1
रूप में कम क्यों?
मेरा मानना है कि @bgusach ने पूरी तरह उत्तर दिया; पाइथन पाइथन दुनिया में वस्तुओं का प्रतिनिधित्व करने के लिए C
structs का उपयोग करता C
ints सहित किसी भी वस्तु:
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
PyObject_VAR_HEAD
एक मैक्रो है जो विस्तारित होने पर संरचना में एक और फ़ील्ड जोड़ता है (फ़ील्ड PyVarObject
जो विशेष रूप से उन ऑब्जेक्ट्स के लिए उपयोग किया जाता है जिनमें लंबाई की कुछ धारणा होती है) और, ob_digits
संख्या के लिए मान रखने वाला एक सरणी है। छोटे और बड़े पायथन संख्याओं के लिए आकार में बॉयलर-प्लेट उस संरचना से आता है।
4
बाइट्स की वृद्धि क्यों?
क्योंकि, जब एक बड़ी संख्या बनाई जाती है, आकार (बाइट्स में) sizeof(digit)
का एक बहु है; आप देख सकते हैं कि _PyLong_New
जहां एक नया longobject
लिए स्मृति आवंटन longobject
साथ किया जाता है:
/* Number of bytes needed is: offsetof(PyLongObject, ob_digit) +
sizeof(digit)*size. Previous incarnations of this code used
sizeof(PyVarObject) instead of the offsetof, but this risks being
incorrect in the presence of padding between the PyVarObject header
and the digits. */
if (size > (Py_ssize_t)MAX_LONG_DIGITS) {
PyErr_SetString(PyExc_OverflowError,
"too many digits in integer");
return NULL;
}
result = PyObject_MALLOC(offsetof(PyLongObject, ob_digit) +
size*sizeof(digit));
offsetof(PyLongObject, ob_digit)
लंबी वस्तु के लिए 'बॉयलर-प्लेट' (बाइट्स में) है जो इसके मूल्य को पकड़ने से संबंधित नहीं है।
uint32
लिए typedef
रूप में struct _longobject
को धारण करने वाले हेडर फ़ाइल में digit
परिभाषित किया गया है:
typedef uint32_t digit;
और sizeof(uint32_t)
4
बाइट्स है। यह वह राशि है जिसके द्वारा आप बाइट्स में आकार को देखेंगे जब _PyLong_New
के size
तर्क बढ़ता है।
बेशक, यह सिर्फ C
पाइथन ने इसे लागू करने के लिए चुना है। यह एक कार्यान्वयन विस्तार है और इस तरह आपको पीईपी में ज्यादा जानकारी नहीं मिलती है। यदि आप संबंधित थ्रेड :-) पा सकते हैं तो पायथन-देव मेलिंग सूची कार्यान्वयन चर्चा आयोजित करेगी।
किसी भी तरह से, आपको अन्य लोकप्रिय कार्यान्वयन में भिन्न व्यवहार मिल सकता है, इसलिए इसे एक के लिए न लें।
यह वास्तव में आसान है। पायथन का int
प्राचीन प्रकार का नहीं है जिसका उपयोग आप अन्य भाषाओं से किया जा सकता है, लेकिन इसकी विधियों और सभी चीजों के साथ एक पूर्ण वस्तु है। वह जगह है जहां ओवरहेड आता है।
फिर, आपके पास पेलोड स्वयं है, पूर्णांक का प्रतिनिधित्व किया जा रहा है। और आपकी स्मृति को छोड़कर, इसके लिए कोई सीमा नहीं है।
पाइथन के int
का आकार वह है जो इसे संख्या के साथ थोड़ा ओवरहेड का प्रतिनिधित्व करने की आवश्यकता है।
यदि आप आगे पढ़ना चाहते हैं, तो दस्तावेज़ के प्रासंगिक भाग पर नज़र डालें:
इंटीग्रर्स में असीमित सटीकता है