python - पायथन में बड़े पूर्णांक के लिए स्मृति आवंटन को समझना




python-3.x int (2)

पाइथन बड़े पूर्णांक के लिए स्मृति आवंटित कैसे करता है?

एक int प्रकार में 28 bytes का आकार होता है और जैसे ही मैं int के मान को बढ़ाता रहता हूं, आकार 4 bytes की वृद्धि में बढ़ता है।

  1. शुरुआत में 28 bytes किसी भी मूल्य के लिए 1 रूप में कम क्यों?

  2. 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 का आकार वह है जो इसे संख्या के साथ थोड़ा ओवरहेड का प्रतिनिधित्व करने की आवश्यकता है।

यदि आप आगे पढ़ना चाहते हैं, तो दस्तावेज़ के प्रासंगिक भाग पर नज़र डालें:

इंटीग्रर्स में असीमित सटीकता है





python-internals