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

  • 96
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

今回は、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になった!