Pythonはどのようにして大きな整数にメモリを割り当てますか?
int
型のサイズは28 bytes
であり、int
の値を増やし続けると、サイズは4 bytes
の増分で増加します。
なぜ最初は28 bytes
という低い値に対して1
なのですか?
なぜ4 bytes
の増分?
PS:私はx86_64(64ビットマシン)でPython 3.5.2を実行しています。(3.0+)インタープリターがこのような膨大な数でどのように機能するかについてのポインター/リソース/ PEPは私が何であるかです。探している。
サイズを示すコード:
>>> 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はそれに答えました 完全に; PythonはC
構造体を使用して、Pythonの世界、任意のオブジェクト int
sを含む =:
_struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
_
_PyObject_VAR_HEAD
_ は、展開すると構造体に別のフィールドを追加するマクロです(フィールド PyVarObject
これは、次の概念を持つオブジェクトに特に使用されます。長さ)および、 _ob_digits
_ は、数値の値を保持する配列です。サイズのボイラープレートは、小さいおよび大きいPythonの数値の場合、その構造体に由来します。
なぜ_
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
_を_uint32
_のtypedef
として保持するヘッダーファイルで定義されています。
_typedef uint32_t digit;
_
sizeof(uint32_t)
は_4
_バイトです。これは、__PyLong_New
_のsize
引数が増加したときにバイト単位のサイズが増加するのを確認できる量です。
もちろん、これはC
Pythonがそれを実装するために選択した方法です。これは実装の詳細であるため、PEPには多くの情報がありません。対応するスレッドが見つかった場合、python-devメーリングリストで実装に関するディスカッションが行われます:-)。
いずれにせよ、他の一般的な実装では動作が異なる場合があるため、これを当然のことと考えないでください。
それは実際には簡単です。 Pythonのint
は、他の言語で慣れている種類のプリミティブではなく、メソッドやすべてのものを備えた本格的なオブジェクトです。そこからオーバーヘッドが発生します。
次に、ペイロード自体、つまり表されている整数があります。そして、あなたの記憶を除いて、それに制限はありません。
Pythonのint
のサイズは、数値と少しのオーバーヘッドを表すために必要なサイズです。
さらに読みたい場合は、 ドキュメントの関連部分 をご覧ください。
整数の精度は無制限です