前回の更新記事はこちら。 rfコマンドv1.16.0をリリースした。主にbug fix
🏕 Features
- Remove bug fix code by @buty4649 in https://github.com/buty4649/rf/pull/149
- Fix issue where tab was incorrectly matching as binary file by @buty4649 in https://github.com/buty4649/rf/pull/150
- Increase MRB_IREP_LVAR_MERGE_LIMIT by @buty4649 in https://github.com/buty4649/rf/pull/151
実は実行速度が6倍くらい速くなっていた
v1.15.0の更新記事に書き忘れてしまったのだが、v1.15.0は過去のバージョンに比べて6倍くらい早くなっていた。 1MB、104334行あるテキストファイルで比較してみると違いがわかりやすい。
# テストで使うテキストファイル $ ls -lah /usr/share/dict/american-english -rw-r--r-- 1 root root 962K Jan 20 2022 /usr/share/dict/american-english $ wc /usr/share/dict/american-english 104334 104334 985084 /usr/share/dict/american-english # v1.14.0 $ rf --version rf 1.14.0 (mruby 3.2.0 9e50d67) $ time rf -q -g hello /usr/share/dict/american-english ________________________________________________________ Executed in 31.80 secs fish external usr time 30.13 secs 375.00 micros 30.13 secs sys time 0.96 secs 0.00 micros 0.96 secs # v1.15.0 $ rf --version rf 1.15.0 (mruby 3.2.0 9e50d67) $ time rf -q -g hello /usr/share/dict/american-english ________________________________________________________ Executed in 5.20 secs fish external usr time 3.41 secs 156.00 micros 3.41 secs sys time 1.68 secs 171.00 micros 1.68 secs
圧倒的に改善されている。 なぜ、ここまで速くなったのかというと、なんとビルド時に最適化オプションをつけ忘れていたというオチ。。 最適化オプションをつけただけでこんなに速くなるんですね。。コンパイラすごい。
ちなみに、grepは1secどころか2msすらかからないのですごい。。。
$ time grep -q hello /usr/share/dict/american-english ________________________________________________________ Executed in 1.25 millis fish external usr time 1.04 millis 199.00 micros 840.00 micros sys time 0.22 millis 217.00 micros 0.00 micros
TAB(0x09)がバイナリファイル判定されていた
TABが含まれたファイル(e.g. tsvファイル)をrfに食わせるとバイナリファイルとして判定されていた。
$ echo -e "a\tb" | rf _ Binary file matches.
これは意図した挙動ではないので修正した。
MRB_IREP_LVAR_MERGE_LIMIT を最大まで増やした
最近知ったのだけど、mrubyではローカル変数は255個以上定義できない。 そして、Bindingクラスのインスタンスではローカル変数はデフォルトでは50個以上定義できないようになっている。 これが何が困るかというと、例えば、rfにおいて各行を足し合わせるみたいな処理をするときに、51行以上のファイルがあるとこの制約にかかってしまう。
# すべての行を足し合わせて最後に合計値を出力 $ seq 1 50 | rf -q 's+=_; at_exit{ puts s }' Error: too many local variables for binding (mruby limitation) # 49行なら正しく出力される $ seq 1 49 | rf -q 's+=_; at_exit{ puts s }' 1225
これはとても困る。。 これを緩和するにはMRB_IREP_LVAR_MERGE_LIMITを増やせばいいということがわかった。
ただ、先のローカル変数の定義数の最大値も関係しているのか240が最大値になっている。 ソースを改変せずに定義数を増やす方法がわからなかったので、一旦240にしてある。
ちなみに、この問題はグローバル変数を使うことで回避できる。
$ seq 1 240 | rf -q 's+=_; at_exit{ puts s }' Error: too many local variables for binding (mruby limitation) $ seq 1 240 | rf -q '$s+=_; at_exit{ puts $s }' 28920
しかし、変数に名に $
をつけるのはタイプ数が増えるし、シェルにおいてはシェル変数として解釈されないようにエスケープなどしなくてはならず、個人的にはイマイチなのでなんとか解決策を見つけたい。