ruby メモリーと時間のバランス
大規模処理時の問題
1河川分の処理を全国でやろうとする等で、件数が増えると何かとしんどくなる。
私の扱う分野では、入出力がネックになる場合が多い。GISのメッシュデータ等、Ⅰ河川でも、千万を超える場合がある。1件1行で逐次出力すると、1000万レコードに30分以上かかったりする。それをPCでやる場合、システムbusyが生じる。
対応策として、全部結合したデータをまとめて出力することが有効である。
しかし、全てを1回で出力する場合、今度は、メモリー不足の問題が出てくる。
メモリーと時間の最適バランス
両者のバランスをどうとるか。正確には、使えるメモリーと時間の状況に応じて変化し、メモリー増設に要する費用と、時間の単価や期限要求を考慮して最適バランスが設定されるが、簡単には、その平方根で割り当てるのが目安になろう。
1000万件のデータであれば、3100行ずつ、3100回出力するということ。
1件ずつ1000万回出力なら、30分+書き込み時間(数分)くらいかかるだろう。
1000万件まとめて1回出力なら、出力だけで1Gbyte以上のメモリーを要するだろう。
3000件のメモリーは、300K、3000回の出力は、数秒+書き込み時間(数分)
少し読みにくいが、下のような書き方をすればよいわけだ。
逐次出力・・・遅い
datas.each{|vals| fo.print vals*"\t" }
1回出力・・・メモリー負荷大
fo.print datas.map{|vals| vals*"\t"}*"\n"
バランス・・・読みにくい
datas.each_slice((datas.size**0.5).to_i){|subs| fo.print subs.map{|vals| vals*"\t" }*"\n"}
cygwin/ruby プロセスメモリー使用状況の把握
linuxであれば、ps -f -l 等で、プロセスメモリーを把握できるが、
cygwin で、ps -f -l 等で、メモリー状況は報告されない。
windowsでは、taskmanagerでメモリー状況を把握できるが、cygwinコマンドでは、tasklist がある。
tasklist /FI "IMAGENAME eq ruby.exe" で、ruby.exe リストを把握できる。ただし、ruby.exe スクリプト名 は表示されないため、
複数ある場合には、注意が必要である。
win32ole/IE メモリーの変動と節約
どうも、cygwin/rubyで、win32ole/IEを使っていると、IEのquit,newで、どんどんメモリーが増えていくように思う。(よくわからない)
IEでのnavigateの回数が増えても、IEが不安定になり、IEを作り直すと、rubyが不安定になる。
このため、一定回数IE.newを繰り返したところで、rubyプロセスを再起動することも有効だろう。
(加筆2019.12.6) 同様のことは、f=open("| gzip FILE","r") のような場合で、fをcloseせずに、ループで上書きすると、gzipが残ったままになる。数百回で、固まってしまう。これについては、closeすれば解消する。
IE起動設定
IE起動時の初期頁は、複数頁設定することが可能であるが、OLE実行時に、重たい頁を開くのは、避けるべきである。それだげ、数百Mbyteのメモリーを消費する。
シンプルな頁1個のみを起動時頁に設定しておくとよい。
これでも、頁更新を重ねると、履歴データが増大する。
特に、動画広告の多い頁では、問題がある。
textを取得する場合、IE設定で、動画、音楽、画像をダウンロードしない設定でよい。
※今思えば、これまで様々なデータのダウンロードに苦労したのは、ホーム設定していたPCメーカーHPが重たく、300Mも使っていたことによるところが大きいようだ。
メモリー増大処理の回避
しばしば、大量の処理を行うにあたり、ファイル全体をmapで読み、mapで処理を重ねて、出力するということを行う。
段階毎に配列を無名メモリーに取り込み、それが解放されないということがあるため、大規模データの場合、メモリーの使い方に注意し、
処理方法を見直そう。
1行ずつの処理で良い場合は、配列に取らずに処理する。
特定のフィールドのみ使う場合には、each処理の中で、A.push(F[0])のように。
連続3行毎の処理で良い場合には、each_cons(3)や、each_slice(3)を使う。
メモリーは、余裕を持って装着しておきたいが、仕方の無いときは、節約する必要がある。
上記のwin32ole/IEの際も、500MB程度以上になると、異常に遅くなり、エラーも生じやすくなる。
課題
大げさなタイトルを付けたが、とりあえず、出力関係の話、IE処理中のメモリーの節約方法等を書いた。他にも様々なことがあろうが、追って加筆したい。