配列のメモリ使用量を調べたりする

メモ。

>>> def ps(): os.system("ps -p %d u" % os.getpid())
... 
>>> import os
>>> ps()
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
takeyuki 30831  0.0  0.0   7188  2604 pts/7    S+   14:05   0:00 python
>>> import numpy
>>> ps()
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
takeyuki 30831  0.1  0.1  19104  5804 pts/7    S+   14:05   0:00 python

ほう。NumPy をインポートするだけで 7 MB から 19 MB に増えるのね。400 万 x 7 の行列を読み込んでみる。

>>> a = numpy.loadtxt('array.txt')
>>> ps()
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
takeyuki 30831 42.9 22.4 948644 931864 pts/7   S+   14:05   1:25 python

950 MB に増えた。28 M 個の値だから、ひとつの値につき 33 Bytes ほど使っていることになるのかな。あれー double だとしても 8 Bytes しか使わないよねえ。

>>> type(a)
<type 'numpy.ndarray'>
>>> type(a[0][0])
<type 'numpy.float64'>

64 bits、つまり 8 Bytes の浮動小数点数ってことだよね。ndarray 型だと array 計算を速くするための特別な情報が埋め込んであるんだろうか。

今度はファイルから読み込まずにやってみるか。

>>> a = numpy.array([0.0 + x for x in xrange(28000000)])
>>> type(a[0])
<type 'numpy.float64'>
>>> ps()
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
takeyuki 30879  6.9 16.0 678860 665600 pts/7   S+   14:20   0:18 python

今度は 680 MB。ひとつの値につき 24 Bytes ...。

>>> a.reshape(7, 4000000)
array([[  0.00000000e+00,   1.00000000e+00,   2.00000000e+00, ...,
          3.99999700e+06,   3.99999800e+06,   3.99999900e+06],
       [  4.00000000e+06,   4.00000100e+06,   4.00000200e+06, ...,
          7.99999700e+06,   7.99999800e+06,   7.99999900e+06],
       [  8.00000000e+06,   8.00000100e+06,   8.00000200e+06, ...,
          1.19999970e+07,   1.19999980e+07,   1.19999990e+07],
       ...,
       [  1.60000000e+07,   1.60000010e+07,   1.60000020e+07, ...,
          1.99999970e+07,   1.99999980e+07,   1.99999990e+07],
       [  2.00000000e+07,   2.00000010e+07,   2.00000020e+07, ...,
          2.39999970e+07,   2.39999980e+07,   2.39999990e+07],
       [  2.40000000e+07,   2.40000010e+07,   2.40000020e+07, ...,
          2.79999970e+07,   2.79999980e+07,   2.79999990e+07]])
>>> ps()
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
takeyuki 30879  4.7 16.0 678860 665688 pts/7   S+   14:20   0:18 python

おお、reshape はすぐ返ってきた。まあ、そうか。

array モジュールも調べておくか。

>>> import array
>>> a = array.array('d', [0.0 + x for x in xrange(28000000)])
>>> ps()
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
takeyuki 30927  6.8 15.9 667040 662572 pts/7   S+   14:30   0:16 python

ふーん。numpy.array をファイルから読み込まないで初期化したときと同じくらいだ。ふーん。どういうことなんだろう。