80 howm-mode.vim (2-43) データ量増大による検索速度の低下を回避する( globpath() )

ダウンロード

はじめにダウンロードのためのURL

http://khkh.o0o0.jp/vim/howm_vim.patch.20080414

欠陥「検索速度の低下」

howm-mode.vim にはいくつのかの欠陥がある。その一つが検索速度の低下である。今回は、その検索速度の低下に対処したいと思う。

howm の構造を簡単に説明していまうと、「ファイル(メモ)を作成し、必要に応じてそれらを grep 検索する」これだけのものだ。浮沈TODOだとか、予定一覧だとか、action-lock だとか言ってるが、それらも検索機能(一覧表示)か、メモ作成の補助かにすぎない。grep による全文検索を行っている以上、ファイルが増えるとどうしても速度低下が起きる。

しかし、howmも4年以上使ってると、起動や検索が耐えられないくらい遅くなります;;

仕方なく、前の3年分のデータをバックアップ後に削除しました。多少(以前に比べると劇的に)快適になりました。

http://d.hatena.ne.jp/smeghead/20080325/heavy

引用元では本家 howm だが howm-mode.vim も例外ではない。むしろ、vimgrep を使用していれば、事態はより深刻である。すべてのログをメモリに読み込むわけだから、速度はお世辞にも速いとは言いがたい。私の環境ではデータはたかだか三ヶ月分だが、もうすでに初回検索に10秒程度かかる。

対応策「全文検索しない」

この問題を回避するには、「キャッシュ」や「インデックス」が妥当な手段だろう。ただ、私が思うに、これらの手段はいささか面倒すぎる。なので、私は「全文検索しない」ことにした。そもそも、全文検索しようとするから時間がかかってしまう。全文検索などやめてしまえばいい。どうせ普段検索するのは、その日と前後一週間程度だろう。必要なファイルだけを検索すればいい。

具体策「globpath()」

Vim には globpath() という関数がある。Version 6 から追加された関数だ。これを利用して、不必要なファイルで vimgrep しないようにしてやる。

for file in split(globpath(searchPath, '**/*.*'), "\<NL>")
  if isdirectory(file) | continue | endif
  let file = escape(file, ' ')
  silent! execute hide 'vimgrepadd /'. searchWord .'/j' file
endfor

おおよそこんなところだ。 vimgrepadd を使えば、quickfix リストに検索結果を徐々に追加していける。

無視するファイルの設定「グローバルオプション wildignore/グローバル変数 howm_wildignore」

「で、無視するファイル云々はどうなったの」そんな疑問がわくと思う。ここで重要なのが「 globpath() はグローバルオプション wildignore を考慮する」ということだ。 wildignore を使えば、globpath() で列挙されるファイルを抑制できる。既にこういう便利なオプションがあるのだから、これを利用しない手はない。ただ、グローバルオプションをそのまんま変更すると影響が大きすぎるため、グローバル変数 howm_wildignore を用意してやる。それを try とかでくくってだな、うん。コードを書いても面倒なだけなので、必要なら使ってみてほしい。

設定例を挙げておく。自分はとりあえず、2008年の1月2月のファイルは無視したい。だから、以下のようにしてある。特に面白い設定でもない。

let g:howm_wildignore = '*/2008-0[12]*.howm'

誤爆する可能性もあるだろうが、まあいざとなったら let g:howm_wildignore = '' とでもしてから、検索してやれば全文検索になるので、問題はない。

wildignore の設定については、ヘルプを参照すると良い。globpath() についてもついでに調べた方が良いかもしれない。

:h globpath()
:h wildignore

小さいけど大きな修正「タイトル行でもキーワードを強調」

あと、小さな修正として、タイトル行でもキーワードや予定などが強調されるよう修正した。