著作一覧 |
一昨昨昨日の東京Ruby会議でWin32OLEについて話したことが正しくなかったということを昨日書いた。
それでは一体、インプロセスかつインスレッドならどのくらいの速度になるのだろうか?
作って試してみた。
元々98.273621秒だったxlsemb.rbは20.201156秒となった。
次に75.0033秒だったxlsemb2.rbは18.596063秒となった。
元の外部プロセス呼び出しが約160秒だったから、1/8に高速化したことになる。クロススレッド版と比較しても1/4。
結局、通信は遅いといういつもながらの知見となるのだった。
興味がある人は、インプロセス版RubyizeオブジェクトをGRScript19-1.3.0.zipに置いたので使ってみてください。
インストール方法:Administrator権限で(Ruby-1.9.2インストールパッケージを利用するとスタートメニューにRuby Console(Administrator)というのが作られているのでそれを利用する)Ruby-1.9.2をインストールしたディレクトリのbinディレクトリへGRScript19.dllをコピーする(置き換える)。
次に、同じディレクトリでコンソールからRegsvr32 GRScript19.dll
を実行する。新規にRubyizeのレジストリ登録が必要なため。
インプロセス/スレッド版のRubyizeのProgIDは、"rubyize.object.1.9"なので、VBAで利用する場合は、 Set ruby = CreateObject("rubyize.object.1.9")
のように記述する。
ラウンドトリップを減らすとか、通信先のノードを自ノードにするというような方法とは別に、そもそも細かな単位では通信しないというやり方があって、もちろん速いはずだ。
テキストの設定で良いのなら、クリップボードでの一括転送という方法がある。via @jitte どうもありがとう。
ジェズイットを見習え |
ええと、Excelの場合、Rangeオブジェクトは、Rubyの二次元配列と双方向でデータの交換ができて、しかも大変高速です。ご参考まで。<br>大分端折りますけどこんな感じ。応用はいくらでも。<br>xl = Win32OLE.new("Excel.Application")<br>wb = xl.workbooks.open("hoge.xls")<br>sh = wb.workSheets("fuge")<br>ar = sh.range("A1:IV4096") #別にIV65535でもぜんぜんOK<br>result = ar.map{|rows|<br> rows.each{|cell| cell.do_something }<br>}<br>sh.range("A1:IV4096") = result
ああ、やったちゃった。ar = sh.range("A1:IV4096").value<br>です
どうもありがとうございます。<br>2次元配列技(と、今命名した)が、jun66j5さんも教えてくれたところをみると、一番に選択すべき高速手法なんですね。