NumPy簡単実験:配列のときの数値の記憶のされ方


2016年 12月 18日

Pythonでは、数値もオブジェクトである。そのため、相当無駄にメモリが使われてしまうことが分かった。
要するに、Pythonでいっぱい計算するのは、メモリ浪費があるから気をつけなければならない。
しかし、Pythonがよく使われるDeep Learningなどでは、大量の数値データを扱うのが普通だ。それも浮動小数点数になるので、全て別々のオブジェクトになる。

と考えると、PythonはAIには全然向いていない。
でも、良く使われている。

といっても、素のPythonを使うことはなく、PythonにNumPyをインポートし、さらに色々なものをインポートして使う訳だ。
そもそも、Pythonにはリストはあっても配列がない。そして、リストは、その性格上遅い。

ということで、NumPyの配列がどのくらいメモリを食うか調べてみる。
前回と同じサイズで、1000万要素の配列を作って調べた。

>>> import os,pusutil,numpy
>>> current_process = psutil.Process(os.getpid())
>>> import os, psutil, numpy
>>> current_process = psutil.Process(os.getpid())
>>> sz0 = current_process.memory_info().rss
>>> a = numpy.array([i for i in range(10000000)])
>>> sz1 = current_process.memory_info().rss
>>> sz1-sz0
80531456

最初に必要そうなものを全部importした。
numpy.arrayに、要素数1000万個のリストを渡して配列を作った。
渡した巨大なリストは、用済みになった時点で消えるはずである。
メモリ使用量は80531456バイトであり、1要素あたり8バイト強しか増えていない。

さらに確認のため、配列オブジェクトについて調べてみる。

>>> type(a)
<class 'numpy.ndarray'>
>>> sys.getsizeof(a)
80000096

ちゃんとnumpy.ndarrayという型になっており、1000万要素の配列のバイト数は、8000万96バイトになっている。余分の96バイトは、配列オブジェクトの管理用などに使われていると思われる。

Pythonのリストでは、1要素あたり40バイトも増えていたのが、実際のデータのサイズと思える8バイトだけの増加になっている。
このことから、NumPyの配列では、数値自体はオブジェクトになっていないと言える。
つまり、C言語などと同じように、配列に直接数字が入っているのだ。