Verständnis der Speicherzuweisung für große Integer in Python

Wie verteilt Python Speicher für große Integer?

Ein int Typ hat eine Größe von 28 bytes und da ich den Wert des int erhöht habe, erhöht sich die Größe in Schritten von 4 bytes .

  1. Warum 28 bytes anfangs für jeden Wert so niedrig wie 1 ?

  2. Warum Schritten von 4 bytes ?

PS: Ich laufe Python 3.5.2 auf einem x86_64 (64-Bit-Maschine). Irgendwelche Zeiger / Ressourcen / PEPs auf, wie die (3.0+) Dolmetscher an so großen Zahlen arbeiten, ist, was ich suche.

Code, der die Größen veranschaulicht:

 >>> 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 

2 Solutions collect form web for “Verständnis der Speicherzuweisung für große Integer in Python”

Warum 28 Bytes anfangs für jeden Wert so niedrig wie 1 ?

Ich glaube, @bgusach antwortete das ganz; Python verwendet C Strukturen, um Objekte in der Python-Welt darzustellen, alle Objekte einschließlich int s :

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

PyObject_VAR_HEAD ist ein Makro, das beim Erweitern ein weiteres Feld in der Struktur (Feld PyVarObject das speziell für Objekte verwendet wird, die einen Begriff der Länge haben) und, ob_digits ist ein Array mit dem Wert für die Zahl. Kesselplatte in der Größe kommt von dieser Struktur, für kleine und große Pythonzahlen.

Warum Schritten von 4 Bytes?

Denn wenn eine größere Zahl erzeugt wird, ist die Größe (in Bytes) ein Vielfaches der sizeof(digit) ; Sie können das in _PyLong_New sehen, wo die Zuweisung von Speicher für ein neues longobject mit 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) ist die ' offsetof(PyLongObject, ob_digit) ' (in Bytes) für das lange Objekt, das nicht mit dem Halten seines Wertes verwandt ist.

digit ist in der Header-Datei definiert, die das struct _longobject als typedef für uint32 :

 typedef uint32_t digit; 

Und sizeof(uint32_t) ist 4 Bytes. Das ist die Menge, mit der du die Größe in Bytes sehen wirst, wenn das size auf _PyLong_New zunimmt.


Natürlich ist das genau so, wie C Python sich dafür entschieden hat. Es ist eine Implementierung Detail und als solche finden Sie nicht viel Informationen in PEPs. Die python-dev-Mailingliste würde Implementierungsgespräche führen, wenn man den entsprechenden Thread finden kann :-).

So oder so kann man in anderen populären Implementierungen unterschiedliches Verhalten finden, also nimm das nicht für selbstverständlich.

Es ist eigentlich einfach Pythons int ist nicht die Art von primitiv, die Sie aus anderen Sprachen verwendet werden können, sondern ein vollwertiges Objekt, mit seinen Methoden und allen Sachen. Hier kommt der Overhead.

Dann hast du die Nutzlast selbst, die ganze Zahl, die dargestellt wird. Und es gibt keine Begrenzung dafür, außer dein Gedächtnis.

Die Größe eines Python's int ist, was es braucht, um die Zahl plus ein wenig Overhead darstellen.

Wenn Sie weiter lesen wollen, werfen Sie einen Blick auf den relevanten Teil der Dokumentation :

Integers haben unbegrenzte Präzision

  • Warum ist es langsamer, über eine kleine Saite zu reißen als eine kleine Liste?
  • Über Pythons eingebaute Art () -Methode
  • Wie groß kann die Eingabe der Pythons input () Funktion sein?
  • Warum erzeugt eine Klassendefinition immer denselben Bytecode?
  • 'Bestellen' von ungeordneten Python-Sets
  • Was ist der Unterschied zwischen einem umgekehrten Tupel und einer umgekehrten Liste?
  • Python 2 vs python 3 Leistung von zufälligen, vor allem `random.sample` und` random.shuffle`
  • Warum sind Integer-Divisionen beim Kompilieren auf Bytecode nicht optimiert?
  • List comprehension filtering - "die set () trap"
  • Runtime von python's if substring in string
  • Python-String wörtliche Verkettung
  • Python ist die beste Programmiersprache der Welt.