Grepが遅い件

1691 letters | 956 views | コメントする

久し振りというか、もう忘れかけてた真魚を更新するぞと。
バグでもないんだけどまずい方法をやっていた部分で相性問題が出たので修正し、
ついでだからちょっとばかしいじろうかなとか思ってるところ。
しかしもうだいぶ忘れてるので、うまくいくかどうかわからない。
まぁ、どっちにしろ修正した分については近日中にアップするが。

で、問題とするのは掲示板にあったGrepの問題だ。
何と比べたかは忘れたが、比べて断然速かったので、遅いんじゃないかと疑いもしなかった。
しかし遅いっていうなら遅いのだろうから、速くなるように考えてみようじゃないか。
そのなんとかっていうソフトはダウンロードしてないので、見ないで書くけれども。

遅いってのは、何かをするのに時間がかかっているということだから、
真魚がなにか余計な事をして時間をかけている所を探してやめさせるしかない。
さて、Grepでどんな処理をしているか、ソースコードを追いかけてみる。

指定されたディレクトリでファイルをリストアップするとか、子ディレクトリをリストアップするとか、
ファイルIO周りはWindowsAPIなので、ソフトによって差が出ることはないはず。
いや、API使うよりもっと高速な独自アクセスをやってるというなら、それにはかなわないが。
現実的な話だけすれば、この後の、ファイルを読み込んで文字列を検索する部分だけの差だ。

真魚の場合、見つかったファイルはとりあえず丸ごと読み込んで、
文字コードの判定をしてから、行に分割し、BM法か鬼車で検索、という手順を踏む。

え?ということは、指定したディレクトリに巨大動画ファイルとかあったら最悪じゃん。
一応、そういうことがないようにするため、拡張子フィルタも付いているのだが、
そんな仕組みがわからなければどうせ*.*で全ファイルを検査しちゃうよな。
自分でもそんなフィルタを使ったことが一度もない。
じゃあさ、*.*を指定しても動画ファイルを全部読みこむことのないように工夫するか?
AdMenuによるテキストファイル判定はかなりの確率でバイナリファイルをはじくので、
ファイルを丸ごと読み込む前に判定ではじいてみようか。
しかそれは精度がよくないので、一部のテキストファイルさえもはじいてしまうのだが。

つぎに、ファイルを読み込んだ後、文字コードを自動判定してユニコードに変換する。
ファイルの中身がSJISだったらSJISのままで検索するなんて器用なことはせず、
すべてユニコードに直してからの検索なので、それ以外のファイルの検索は遅い。
変換の速度はこれ以上上がらないので、この部分を速くするのは不可能。
改行コードの変換もやっているが、これは¥nで¥r¥nも探させる都合上、やむを得ない。
検索スピードを上げるわけにもいかず、ほかにスピードを上げる術はない。

というわけで、Grepが遅くなる原因は、バイナリファイルをはじいていないことと、
テキストファイルをユニコードでLFなファイルに変換していることなのだが、
後者はどうしようもなく、前者は多少のデメリットがある。
つまりこれ、もう高速化できないっぽい。
でも、ユーザーが拡張子のフィルタではじいて高速化はできるので、
フィルタをもっと使いやすくできればいいのだがそれも面倒だな。
何も更新できないっぽい。

たぶん関連のある記事:

コメントは終了しています。