カーソル移動が遅かったのでprofileしてみた。
以下のような関数をvimrcに書く。
function! ProfileCursorMove() abort
let profile_file = expand('~/log/vim-profile.log')if filereadable(profile_file)call delete(profile_file)endif
normal! gg
normal! zR
execute 'profile start '. profile_file
profile func *
profile file *
augroup ProfileCursorMove
autocmd!
autocmd CursorHold<buffer> profile pause |q
augroup END
foriin range(100)call feedkeys('j')endforendfunction
profile_file
はプロファイルの結果がで出るファイル。~/log
ディレクトリは予め作っておく。
使い方は
$ vim +'call ProfileCursorMove()' <カーソルを動かすのが重いファイル>
上記コマンドを実行するとfeedkeys('j')
によって、100回jが実行される。feedkeys()
はキー実行を待たず、非同期で実行されるので、profile pause | q
をすぐ下に書くと、キー実行が終わる前にvimが終了してしまう。そこで、CursorHold
を使い、カーソルが動かなくなったら終了するように書いた。
実行後にprofile_file
の下を見ると、各関数毎にかかった時間が書いてある。
FUNCTIONS SORTED ON TOTAL TIME
count total (s) self (s) function
306 0.106875 0.008378 fugitive#head()
306 0.083811 0.018949 <SNR>37_repo_head()
306 0.041424 0.033768 <SNR>37_repo_head_ref()
612 0.027759 <SNR>37_repo()
101 0.022314 <SNR>62_Highlight_Matching_Pair()
306 0.010365 <SNR>37_sub()
612 0.007656 <SNR>37_repo_dir()
ステータスラインにブランチ名を表示させるために使っているfugitive#head()
が重い。
ステータスラインの表示にitchyny/lightline.vimを使っているが、そのREADMEを見るとブランチ名表示用にitchyny/vim-gitbranchというのがあるので試してみた。
FUNCTIONS SORTED ON TOTAL TIME
count total (s) self (s) function
306 0.046956 gitbranch#name()
101 0.024812 <SNR>58_Highlight_Matching_Pair()
204 0.005348 GetCurrentColumn()
102 0.004285 lightline#link()
fugitive#head()
に比べると倍くらい早いがまだ一番重い。Highlight_Matching_Pair()
も結構重いが、これはitchyny/vim-parenmatchというプラグインを代わりに使うと、精度は多少落ちるが軽くなる1。
ただし、このプラグインを使うとマッチした括弧のハイライトが下線になってしまうので、元と同じハイライトにするには、vimrcでcolorschemeを呼び出している箇所より後に
highlight link ParenMatch MatchParen
を書き、どこかに
letg:parenmatch_highlight=0
を書く。
vim-parenmatchにした結果は、
FUNCTIONS SORTED ON TOTAL TIME
count total (s) self (s) function
306 0.045896 gitbranch#name()
101 0.005845 parenmatch#update()
204 0.005454 GetCurrentColumn()
102 0.003950 lightline#link()
306 0.002518 MyFileencoding()
parenmatch#update()
のほうが大分早い。
しかし、カーソルを動かしてみるとまだまだ遅い。
'cursorline' を必要な時にだけ有効にする - 永遠に未完成の設定をやってみた。
めっちゃ早くなった。
設定前
$ time vim +'call ProfileCursorMove()' <カーソルを動かすのが重いファイル>
vim +'call ProfileCursorMove()' 6.03s user 4.06s system 96% cpu 10.496 total
設定後2
$ time vim +'call ProfileCursorMove()' <カーソルを動かすのが重いファイル>
vim +'call ProfileCursorMove()' 1.30s user 0.54s system 91% cpu 2.015 total
よくよく考えると、関数で一番重いものでもトータルで0.1秒程度しか寄与してないので、関数は関係なかった。
ちなみにカーソル移動以外でかかっている時間は
$ time vim +'q' <カーソルを動かすのが重いファイル>
vim +'q' 0.87s user 0.29s system 90% cpu 1.276 total
なので、カーソル移動には0.7秒くらいかかっているようだ。
Vimの標準プラグインmatchparenが遅かったので8倍くらい速いプラグインを作りました - プログラムモグモグ: 作者による解説記事。 ↩
ただし、
+command
で起動するとWinEnterのイベントが発生しないらしく、ブログではlet s:cursorline_lock = 0
となっている箇所を0にした。 ↩