Pythonリスト(タプル)には要素ごとに何バイトありますか?
-
02-07-2019 - |
質問
たとえば、100万(32ビット)整数のリストを保存するために必要なメモリ量はどれくらいですか?
alist = range(1000000) # or list(range(1000000)) in Python 3.0
解決 2
便利なリンク:
Pythonオブジェクトのメモリサイズ/使用量を取得する方法
しかし、彼らは決定的な答えを与えません。方法:
-
リストあり/なしでPythonインタープリターが消費するメモリを測定します(OSツールを使用)。
-
ある種のsizeof(PyObject)を定義するサードパーティの拡張モジュールを使用します。
更新:
レシピ546530:Pythonオブジェクトのサイズ(改訂)
import asizeof
N = 1000000
print asizeof.asizeof(range(N)) / N
# -> 20 (python 2.5, WinXP, 32-bit Linux)
# -> 33 (64-bit Linux)
他のヒント
"それは依存します。" Pythonは、要素を追加するための償却された一定時間を達成するような方法でリストにスペースを割り当てますリスト。
実際には、これが現在の実装で意味することは...リストには常に2のべき乗数の要素に割り当てられたスペースがあります。したがって、range(1000000)は、実際には2 ^ 20個の要素(〜104万個)を保持するのに十分な大きさのリストを割り当てます。
これは、リスト構造自体(各要素のPythonオブジェクトへのポインターの配列)を格納するために必要なスペースのみです。 32ビットシステムは要素ごとに4バイトを必要とし、64ビットシステムは要素ごとに8バイトを使用します。
さらに、実際の要素を保存するスペースが必要です。これは大きく異なります。小さな整数(現在-5〜256)の場合、追加のスペースは必要ありませんが、より大きな数値の場合、Pythonは各整数に10〜100バイトのメモリを断片化する傾向がある新しいオブジェクトを割り当てます。
下の行:複雑です。Pythonリストは、大規模な同種のデータ構造を格納するのに適した方法ではありません 。そのためには、 array
モジュールを使用するか、ベクトル化された数学を行う必要がある場合は、NumPyを使用します。
PS-リストとは異なり、タプルは、要素が徐々に追加されるように設計されていません。アロケータがどのように機能するかはわかりませんが、大規模なデータ構造にアロケータを使用することは考えていません:-)
アドレス指定" tuple&quot ;;質問の一部
典型的なビルド構成でのCPythonのPyTupleの宣言は、次のように要約されます。
struct PyTuple {
size_t refcount; // tuple's reference count
typeobject *type; // tuple type object
size_t n_items; // number of items in tuple
PyObject *items[1]; // contains space for n_items elements
};
PyTupleインスタンスのサイズは構築中に固定され、その後変更することはできません。 PyTupleが占めるバイト数は次のように計算できます
sizeof(size_t)x 2 + sizeof(void *)x(n_items + 1)
。
これにより、タプルのサイズが浅になります。 フルサイズを取得するには、 PyTuple :: items []
配列をルートとするオブジェクトグラフが消費する合計バイト数も追加する必要があります。
タプル構築ルーチンは、空のタプルの単一インスタンスのみが作成されるようにする(シングルトン)ことに注意してください。
参照: Python.h 、 object.h 、 tupleobject.h 、 tupleobject.c
新しい関数
getsizeof()
は、 Pythonオブジェクトと量を返します オブジェクトが使用するメモリの測定 バイト単位。組み込みオブジェクト 正しい結果。第三者 拡張機能はそうではないかもしれませんが、定義できます オブジェクトのサイズを返す__ sizeof __()
メソッド。
kveretennicov@nosignal:~/py/r26rc2$ ./python
Python 2.6rc2 (r26rc2:66712, Sep 2 2008, 13:11:55)
[GCC 4.2.3 (Ubuntu 4.2.3-2ubuntu7)] on linux2
>>> import sys
>>> sys.getsizeof(range(1000000))
4000032
>>> sys.getsizeof(tuple(range(1000000)))
4000024
明らかに返された数値には、含まれているオブジェクトによって消費されるメモリは含まれていません(sys.getsizeof(1)== 12)。
これは実装固有のものであり、かなり確信しています。確かにそれは整数の内部表現に依存します-Pythonが任意の大きな整数を与えて小さなintがよりコンパクトに格納されるので、それらが32ビットとして格納されるとは仮定できません。
私のPython(コア2デュオのFedora 9の2.5.1)では、割り当て前のVmSizeは6896kB、後は22684kBです。さらに100万個の要素を割り当てた後、VmSizeは38340kBになります。これは、1000000整数に対して約16000kBを非常に大まかに示しており、整数あたり約16バイトです。これは、リストのオーバーヘッドの多くを示唆しています。私はこれらの数字をひとつまみの塩で取ります。
なぜあなたが尋ねているのか警戒しています。特定の実装に必要なメモリ量を把握しようとしていますか?たとえば、10,000,000個のウィジェットを読み取り、それがどれだけのRAMを消費するかを知りたいと考えていますか?
その場合、各ウィジェットが必要とするRAMの量を把握するのではなく、10,000個のウィジェットが必要とするRAMの容量を把握し、実際のサイズを得るために乗算します。