memorandums

日々のメモです。

Ruby1.9.1のcsv.rbではまる→強制的に解決

企業との共同研究で開発してきた物流シミュレータ「流」。物流規則をDSLっぽくしたかったのでRubyのお力を借りています。Rubyは1.8.7で開発してきました。といってもRubyでまじめにプログラムを書いたのは今回が初めてなので大したことはやっていません。不勉強です。

今年の共同研究はこのシミュレータを高速化しようということになりました。で、Ruby1.9は1.8より高速と聞いたことがあったので、とりあえず試して見ました。マシンはmacbook air初代(10.6.3)です。

で、ちょっと今日は時間がないので手短に書きたいと思いますが。。。実は、Ruby1.9.1に対応させるのに少々時間がかかりました。とりあえず各rbファイルの先頭にマジックコメントを追加するとエラーが無くなりました。しかし。。。それ以降が大変。タイトルの通り、csv.rbについてです。

本シミュレータはExcelCSVファイルでインタフェースするためcsv.rbを利用させてもらっています。これが1.8と1.9では少々違うようです。文字化けしたり、CSV.openを呼び出しても処理が止まったり。。。あれこれしました。

結局、どうしたか。。。といいますと、/usr/local/lib/ruby19/1.9.1/csv.rbの以下の行を書き換えました。read_to_charメソッド内でencode_strを呼び出しているのですが、ここで例外が発生してretryを繰り返してしまいます。そこで、例外の元となっているencodeメソッドを呼ばないように(ファイルから読み込んだデータをそのまま配列化)しました。これでOKでした。

2264 # chunks.map { |chunk| chunk.encode(@encoding.name) }.join
2265 chunks.map { |chunk| chunk }.join

ちなみに、1.8.7のときにはCSV.openを使っていたのですが、これをCSV.foreach()に書き換えました。以下のような感じです。

# CSV.open(@path+"/"+@filename+".csv", "r") do |row|
CSV.foreach(@path+"/"+@filename+".csv",:encoding=>"UTF-8") do |row|

本来的な解決方法ではありませんし、そもそもCSVライブラリの使い方が間違っている可能性があるのですが、とりあえず何かの情報になればと思いここに書くことにしました。スクリプト言語デバッグはやはり大変です。。。途中でprintデバッグでは効率が悪いと思い、netbeansに切り替えようとしたら。。。ruby-debugあたりが1.9に対応していない。。。とかメッセージが出て怒られました。そうなんですかね?あきらめてprintデバッグを続けました。。。


で、本来の目的だった処理系の違いによる実行時間ですが。。。以下のようになりました。確かに早くなります。

1.8.7→6.720s

1.9.1→5.237s


ついでにjrubyでも試してみました。結果は以下の通り。

Jruby1.5→15.505s


やはり、アルゴリズムの見直しをしないと行けません。。。という結果になりました。最終的な目的として1/10以下にしたいので。ちゃんちゃん。