ruby-robotの夢

cygwin-ruby,qgisの達人を目指す奮闘記

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起動設定

WIN32OLE/IE時には、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処理中のメモリーの節約方法等を書いた。他にも様々なことがあろうが、追って加筆したい。