Pythonでintデータ型のサイズを確認したい:
import sys
sys.getsizeof(int)
それは「436」であることがわかりますが、それは私には意味がありません。とにかく、intが私のマシンで何バイト(2,4、..?)かかるか知りたいです。
Pythonでintデータ型のサイズを確認したい:
import sys
sys.getsizeof(int)
それは「436」であることがわかりますが、それは私には意味がありません。とにかく、intが私のマシンで何バイト(2,4、..?)かかるか知りたいです。
クラスのインスタンスではなく、クラスのサイズを取得しています。int
インスタンスのサイズを取得するために呼び出します。
>>> sys.getsizeof(int())
24
そのサイズがまだ少し大きいと思われる場合は、Pythonは(たとえば) cint
とは大きく異なることを思い出してください。int
Python では、 anint
は完全なオブジェクトです。これは、余分なオーバーヘッドがあることを意味します。
すべての Python オブジェクトには、他のストレージに加えて、少なくとも refcount とオブジェクトの型への参照が含まれています。64 ビット マシンでは、16 バイトを使用します。内部 (標準のint
CPython 実装によって決定される) も時間の経過とともに変更されたため、使用される追加のストレージの量はバージョンによって異なります。
int
Python 2 および 3 のオブジェクトに関する詳細Python 2 の状況は次のとおりです (この一部は、 Laurent Luceによるブログ投稿から改作されています)。整数オブジェクトは、次の構造を持つメモリ ブロックとして表されます。
typedef struct {
PyObject_HEAD
long ob_ival;
} PyIntObject;
PyObject_HEAD
refcount とオブジェクト タイプのストレージを定義するマクロです。documentationで詳細に説明されており、コードはこの回答で確認できます。
新しい整数ごとに割り当てのボトルネックが発生しないように、メモリは大きなブロックで割り当てられます。ブロックの構造は次のようになります。
struct _intblock {
struct _intblock *next;
PyIntObject objects[N_INTOBJECTS];
};
typedef struct _intblock PyIntBlock;
これらは最初はすべて空です。次に、新しい整数が作成されるたびに、Python は が指すメモリを使用し、ブロック内の次の空いている整数オブジェクトを指すようにnext
インクリメントします。next
通常の整数のストレージ容量を超えると、これがどのように変化するかは完全にはわかりませんが、そうすると、のサイズint
が大きくなります。私のマシンでは、Python 2 で:
>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
24
>>> sys.getsizeof(2 ** 62)
24
>>> sys.getsizeof(2 ** 63)
36
Python 3 では、全体像は同じだと思いますが、整数のサイズはより断片的に増加します。
>>> sys.getsizeof(0)
24
>>> sys.getsizeof(1)
28
>>> sys.getsizeof(2 ** 30 - 1)
28
>>> sys.getsizeof(2 ** 30)
32
>>> sys.getsizeof(2 ** 60 - 1)
32
>>> sys.getsizeof(2 ** 60)
36
もちろん、これらの結果はすべてハードウェアに依存しています。YMMV。
Python 3 の整数サイズの可変性は、可変長型 (リストなど) のように動作する可能性があることを示唆しています。そして実際、これは真実であることが判明しました。Python 3でのオブジェクトのCstruct
の定義は次のとおりです。int
struct _longobject {
PyObject_VAR_HEAD
digit ob_digit[1];
};
この定義に付随するコメントは、Python 3 の整数表現を要約したものです。ゼロは、格納された値ではなく、サイズがゼロのオブジェクトによって表されます (これがsys.getsizeof(0)
is24
バイトでsys.getsizeof(1)
isである理由です28
)。負の数は、負のサイズ属性を持つオブジェクトによって表されます! とても奇妙。