この記事では、Pythonでオブジェクトのサイズ(メモリ消費量)を確認する方法を解説します。
オブジェクトのサイズを確認することでどの程度メモリを使っているのか知ることができます。
それでは、オブジェクトのサイズを確認する方法を見ていきましょう!
object.__sizeof__()を使う
オブジェクトの__sizeof__()メソッドを呼び出すことでそのオブジェクトのサイズをバイト単位で取得することができます。
i = 1 print(f'{type(i)}: {i.__sizeof__()}') f = 1.0 print(f'{type(f)}: {f.__sizeof__()}') s = 'abc' print(f'{type(s)}: {s.__sizeof__()}') l = [1, 2, 3] print(f'{type(l)}: {l.__sizeof__()}') t = (1, 2, 3) print(f'{type(t)}: {t.__sizeof__()}')
実行結果
<class 'int'>: 28 <class 'float'>: 24 <class 'str'>: 52 <class 'list'>: 104 <class 'tuple'>: 48
様々なオブジェクトのサイズを確認することができました。
sys.getsizeof()を使う
sysモジュールのgetsizeof()関数を使うことでもオブジェクトのサイズをバイト単位で確認することができます。この関数は、オブジェクトの__sizeof__()メソッドを呼び出しています。
import sys i = 1 print(f'{type(i)}: {sys.getsizeof(i)}') f = 1.0 print(f'{type(f)}: {sys.getsizeof(f)}') s = 'abc' print(f'{type(s)}: {sys.getsizeof(s)}') l = [1, 2, 3] print(f'{type(l)}: {sys.getsizeof(l)}') t = (1, 2, 3) print(f'{type(t)}: {sys.getsizeof(t)}')
実行結果
<class 'int'>: 28 <class 'float'>: 24 <class 'str'>: 52 <class 'list'>: 120 <class 'tuple'>: 64
オプション引数defaultを指定することでサイズを取得できなかった場合に受け取るデフォルト値を指定できます。サイズが取得できない場合に、デフォルト値が設定されていなければTypeErrorが発生します。
import sys # サイズを取得できないクラス class MyClass: def __sizeof__(self): return None mc = MyClass() print(sys.getsizeof(mc, 48))
実行結果
48
サードパーティー製の型などはサイズが取得できない場合もあるので注意しましょう!
サイズの違い
object.__sizeof__()とsys.getsizeof()では、サイズが異なる場合があります。
import sys l = [] print(f'sys.getsizeof(l): {sys.getsizeof(l)}') print(f'l.__sizeof__(): {l.__sizeof__()}')
実行結果
sys.getsizeof(l): 56 l.__sizeof__(): 40
なぜサイズが異なる場合があるかというとsys.getsizeof()は、ガベージコレクタのフィールド分だけサイズを追加するからその分だけ大きくなることがあるからです。
なので、オブジェクトのサイズを知りたければobject.__sizeof__()を使い、オブジェクトを使用するのに消費されているメモリを知りたければsys.getsizeof()を使いましょう!
参照先のサイズ
取得したサイズには、参照しているオブジェクトのサイズまでは含まれません。例えば、リストの要素が異なっていてもサイズに変化はありません。
import sys l = [[]] m = sys.getsizeof(l) print(l, m) l = [[1, 2, 3]] m = sys.getsizeof(l) print(l, m)
実行結果
[[]] 64 [[1, 2, 3]] 64
このように、参照するオブジェクトのサイズは含まれないので注意が必要です。もし、参照先のサイズまで調べたい場合は、再帰的に処理することで可能です。
外部リンク再帰的にサイズを割り出す
まとめ
この記事では、オブジェクトのサイズを取得する方法を解説しました。
タプルはリストよりも軽いと言われていますが実際にどの程度メモリを節約できるかは知らなかったりします。そんな時は、__sizeof__を使って比べてみると結構面白いです!
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ


