58

Pythonでintデータ型のサイズを確認したい:

import sys
sys.getsizeof(int)

それは「436」であることがわかりますが、それは私には意味がありません。とにかく、intが私のマシンで何バイト(2,4、..?)かかるか知りたいです。

4

1 に答える 1

124

短い答え

クラスのインスタンスではなく、クラスのサイズを取得しています。intインスタンスのサイズを取得するために呼び出します。

>>> sys.getsizeof(int())
24

そのサイズがまだ少し大きいと思われる場合は、Pythonは(たとえば) cintとは大きく異なることを思い出してください。intPython では、 anintは完全なオブジェクトです。これは、余分なオーバーヘッドがあることを意味します。

すべての Python オブジェクトには、他のストレージに加えて、少なくとも refcount とオブジェクトの型への参照が含まれています。64 ビット マシンでは、16 バイトを使用します。内部 (標準のintCPython 実装によって決定される) も時間の経過とともに変更されたため、使用される追加のストレージの量はバージョンによって異なります。

intPython 2 および 3 のオブジェクトに関する詳細

Python 2 の状況は次のとおりです (この一部は、 Laurent Luceによるブログ投稿から改作されています)。整数オブジェクトは、次の構造を持つメモリ ブロックとして表されます。

typedef struct {
    PyObject_HEAD
    long ob_ival;
} PyIntObject;

PyObject_HEADrefcount とオブジェクト タイプのストレージを定義するマクロです。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)。負の数は、負のサイズ属性を持つオブジェクトによって表されます! とても奇妙。

于 2012-04-28T17:00:54.380 に答える