質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

1回答

1605閲覧

__slots__ でのメモリの節約について

thinkn1108

総合スコア45

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

0クリップ

投稿2018/10/20 11:34

質問

Pythonの__slots__self.__dict__を保つ必要がなくなるため、メモリの節約になるという記述を
「実践Python3」のFlyweightパターンの中でみたのですが、実際ためしてみたらそんなことはなかったです。

確かに __slots__を定義するとobj.__dict__は無くなっているので、メモリは節約できているような気がするのですが、
実際にsys.getsizeof()でメモリ使用量を見ると__slots__なしの方がメモリを節約できているのはなんでなのでしょうか?

サンプルコード

python

1import sys 2 3 4def main(): 5 print(sys.getsizeof(Point1)) # => 888 6 print(sys.getsizeof(Point2)) # => 1056 7 8 p1 = Point1() 9 p2 = Point2() 10 11 print(sys.getsizeof(p1)) # => 88 12 print(sys.getsizeof(p2)) # => 56 13 14 # print(p1.__dict__) # => エラーになるので略 15 print(p2.__dict__) # => {'x': 0, 'y': 0, 'z': 0, 'a': 0, 'b': 0, 'c': 0} 16 17 18class Point1(object): 19 __slots__ = ['x', 'y', 'z', 'a', 'b', 'c'] 20 21 def __init__(self): 22 self.x = 0 23 self.y = 0 24 self.z = 0 25 self.a = 0 26 self.b = 0 27 self.c = 0 28 29 30class Point2(object): 31 32 def __init__(self): 33 self.x = 0 34 self.y = 0 35 self.z = 0 36 self.a = 0 37 self.b = 0 38 self.c = 0 39 40if __name__ == "__main__": 41 main() 42

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

sys.getsizeof()ではオブジェクトのメモリ使用量は上手く測れません。

オブジェクトに直接起因するメモリ消費のみを表し、参照するオブジェクトは含みません。

29.1. sys — システムパラメータと関数 — Python 3.6.5 ドキュメント #sys.getsizeof

obj.__dict__objが参照しているオブジェクトです。これのメモリ使用量はsys.getsizeof(obj)では見れません。

……困ったことに、参照オブジェクトを含めて上手くメモリ使用量を測れる簡単な手段は実はないのですが。

とりあえずp2.__dict__のサイズを見ましょう。

python

1 # 略 2 3 print(sys.getsizeof(p1)) # => 88 4 print(sys.getsizeof(p2)) # => 56 5 6 # 追加 7 print(sys.getsizeof(p2.__dict__)) # => 192 8 9 # 略

p1そのものは__slots__を使っているため、p2に対して32byteほど余計にメモリを消費しています。

ただし、p2には参照オブジェクトの__dict__があり、これが192byte消費しているので、p1の方が差し引き160byteくらい節約できている、と考えれば良いと思います。
(厳密な正しさは保証しません)

投稿2018/10/20 12:29

編集2018/10/20 13:30
hayataka2049

総合スコア30933

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

thinkn1108

2018/10/20 16:08

なるほど。 `sys.getsizeof()`がメモリ使用量をしっかり測定できていない感はありましたが、 参照オブジェクトという概念は知りませんでした。 勉強になりました。ありがとうございます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問