Posted at

Pythonのメモリ使用量を減らすポイント

More than 3 years have passed since last update.

今回は、iXce’s blog » Blog Archive » Optimizing memory usage in Python: a case study という記事を見つけて興味深かったので紹介したいと思います。何も説明書いてないところがあるので、詳しく知りたい人は元記事を読んでほしいです。


動機


  • プレーンテキストをGコードに変換するプログラムを書いている

  • 3.8MB (14万Gコード) のファイルを読み込むと、244MBもメモリを使ってしまう

  • だからメモリ使用量を減らしたい


やったこと


プロファイル

どこがメモリをたくさん使ってるのか調べるためにHeapyを使う

$ pip install guppy で入れられる。

するとこんな感じの結果が出力される。

Partition of a set of 225737 objects. Total size = 115386656 bytes.

Index Count % Size % Cumulative % Kind (class / dict of class)
0 100000 44 104800000 91 104800000 91 dict of __main__.Hoge
1 100000 44 6400000 6 111200000 96 __main__.Hoge
2 11648 5 1013232 1 112213232 97 str
3 177 0 844360 1 113057592 98 list
4 5849 3 470816 0 113528408 98 tuple

参考: Pythonでメモリ消費量のプロファイルを取る - 西尾泰和のはてなダイアリー


一時データをdelで消す

del temporary_data

こんな感じ


The __slots__ magic

自作クラスの __slots__ に使うattributeを書く

__slots__ = ('x', 'y', 'z')

こんな感じ


tupleのlistをarrayに置き換える

num = ([1, 2], [1, 1], [2, 1])

みたいのをやめて、こうする

x = array('I', [1, 1, 2])

y = array('I', [2, 1, 1])

def num(idx):
return (x[idx], y[idx])


減らす余地のあるtupleを削除


Cython使ってみる


cyclic garbage collectorを捨てる


CythonコードもHeapyで調べる


結果

メモリ使用量が 244MB から 19.4MBになった!