2016-10-31 7 views
28

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

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

  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 

उत्तर

22

क्यों 28 बाइट्स शुरू में 1 जितनी कम किसी भी मूल्य के लिए?

मुझे विश्वास है कि @bgusach answered that पूरी तरह से;

struct _longobject { 
    PyObject_VAR_HEAD 
    digit ob_digit[1]; 
}; 

PyObject_VAR_HEAD एक मैक्रो है कि जब विस्तार struct (क्षेत्र PyVarObject जो विशेष रूप से वस्तुओं है कि के कुछ धारणा है के लिए प्रयोग किया जाता है में एक और क्षेत्र कहते है: अजगर अजगर दुनिया में वस्तुओं का प्रतिनिधित्व करने के C structs, किसी भी वस्तुओं including ints का उपयोग करता है लंबाई) और, ob_digits एक सरणी है जो संख्या के लिए मूल्य रखती है। आकार में बॉयलर-प्लेट उस संरचना से आता है, छोटे और बड़े पायथन संख्याओं के लिए।

4 बाइट्स की वृद्धि क्यों?

क्योंकि, जब बड़ी संख्या बनाई जाती है, आकार (बाइट्स में) sizeof(digit) का एक बहु है; आप देख सकते हैं कि _PyLong_New में जहां एक नया longobject के लिए स्मृति के आवंटन PyObject_MALLOC साथ किया जाता है:

/* 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) 'बॉयलर-प्लेट' है (बाइट्स में) लंबे उद्देश्य यह है कि के साथ संबंधित नहीं है के लिए अपना मूल्य धारण करना

digit पकड़े हेडर फाइल में परिभाषित किया गया है struct _longobject एक के रूप में typedef के लिए uint32:

typedef uint32_t digit; 

और sizeof(uint32_t)4 बाइट है। size_PyLong_New बढ़ने पर तर्क तब होता है जब आप बाइट्स में आकार को देखेंगे।


बेशक

, यह सिर्फ कैसे C अजगर इसे लागू करने के लिए चुना गया है। यह एक कार्यान्वयन विस्तार है और इस तरह आपको पीईपी में ज्यादा जानकारी नहीं मिलती है। यदि आप संबंधित थ्रेड :-) पा सकते हैं तो पायथन-देव मेलिंग सूची कार्यान्वयन चर्चा आयोजित करेगी।

किसी भी तरह से, आपको अन्य लोकप्रिय कार्यान्वयन में भिन्न व्यवहार मिल सकता है, इसलिए इसे एक के लिए न लें।

16

यह वास्तव में आसान है। पायथन का int ऐसी प्राचीन चीज नहीं है जिसका उपयोग आप अन्य भाषाओं से किया जा सकता है, लेकिन इसकी विधियों और सभी चीजों के साथ एक पूर्ण वस्तु है। वह जगह है जहां ओवरहेड आता है।

फिर, आपके पास पेलोड स्वयं है, जो पूर्णांक का प्रतिनिधित्व किया जा रहा है। और आपकी स्मृति को छोड़कर, इसके लिए कोई सीमा नहीं है।

पायथन के int का आकार यह है कि इसे संख्या के साथ थोड़ा ओवरहेड का प्रतिनिधित्व करने की आवश्यकता है।

आप आगे पढ़ने के लिए चाहते हैं, relevant part of the documentation पर एक नज़र डालें:

पूर्णांकों असीमित सटीक

+0

धन्यवाद। क्या कोई पीईपी है जो बताती है कि यह हालिया पायथन संस्करणों (3.0+) में कैसे किया जाता है? – Vigneshwaren

+2

@ विग्नेशवेयर यह आपके द्वारा उपयोग किए जा रहे किसी भी दुभाषिया का कार्यान्वयन विवरण है। पायथन-द-लैंग्वेज केवल गारंटी देता है कि 'int' में मनमाना परिशुद्धता है, न कि यह कैसे पूरा किया जाता है। – chepner

+3

@ विग्नेशवेयर: आप सीपीथॉन के लिए ['sys.int_info'] (https://docs.python.org/3/library/sys.html#sys.int_info) (' long_info' 2.7) से मूल जानकारी देख सकते हैं। असल में, प्रत्येक परिमाण के sys.int_info.bits_per_digit' पूर्ण परिमाण (साइन अप्रासंगिक), या उसके हिस्से को स्टोर करने के लिए अतिरिक्त 'sys.int_info.sizeof_digit' बाइट की आवश्यकता होती है। नोट: छोटे 'int' को सीपीथॉन में कैश किया जाता है, इसलिए एक कार्यान्वयन विस्तार के रूप में, (आईआईआरसी) -5 से 256 के मान सिंगलेट होते हैं; आप पॉइंटर के संदर्भ में केवल 4-8 बाइट्स का भुगतान करते हैं, न कि ऑब्जेक्ट की लागत। – ShadowRanger