読者です 読者をやめる 読者になる 読者になる

Vim scriptは実行されない行を解釈しているので遅いという件についてサンプルコードを書いてみた

vim

元ネタ:map, fold, filter on Vim Script - Togetter



そうなのかー。ということで簡単なサンプルを書いて確認してみた。

サンプルコード

実行結果を最後に載せます。先にサンプルコードから。

ケース1:trueもfalseも短い。基準に使う
function! s:base()
  if 0
    let a = {'a':1}
  else
    let b = {'b':1}
  endif
endfunction
ケース2:falseが上に来ていて、その中のコードが10000行ある
function! s:false_ga_ue_de_nagai()
  if 0
    let a = {'a':1}
    " 以下同じコードが9999行続く
  else
    let b = {'b':1}
  endif
endfunction
ケース3:ケース2と同じだけど、10000行の中身を別関数に切り出してある
function! s:false_ga_ue_de_nagai_kedo_func()
  if 0
    call s:nagai_func()
  else
    let b = {'b':1}
  endif
endfunction

function! s:nagai_func()
  let a = {'a':1}
  " 以下同じコードが9999行続く
endfunction
ケース4:trueが上に来ていて中身も短いんだけど、returnがない。そしてfalse部が10000行。
function! s:true_ga_ue_de_mijikai_kedo_return_nashi()
  if 1
    let b = {'b':1}
  else
    let a = {'a':1}
  " 以下同じコードが9999行続く
endfunction
ケース5:trueが上に来ていて中身も短くてreturnがある。そしてfalse部が10000行。
function! s:true_ga_ue_de_mijikai_kedo_return_ari()
  if 1
    let b = {'b':1}
    return
  else
    let a = {'a':1}
  " 以下同じコードが9999行続く
endfunction

これらに対して簡単に実行時間を計測しました。
計測には以下のプラグインを使っています。
Vim script のベンチマーク - Alone Like a Rhinoceros Horn

let s:bm = benchmark#new("sample")
function! s:bm.base()
  call s:base()
endfunction

function! s:bm.false_ga_ue_de_nagai()
  call s:false_ga_ue_de_nagai()
endfunction

function! s:bm.false_ga_ue_de_nagai_kedo_func()
  call s:false_ga_ue_de_nagai_kedo_func()
endfunction

function! s:bm.true_ga_ue_de_mijikai_kedo_return_nashi()
  call s:true_ga_ue_de_mijikai_kedo_return_nashi()
endfunction

function! s:bm.true_ga_ue_de_mijikai_kedo_return_ari()
  call s:true_ga_ue_de_mijikai_kedo_return_ari()
endfunction

call s:bm.run(3)

実行結果

Benchmark: sample

Trial #1
  true_ga_ue_de_mijikai_kedo_return_ari   : 0.000030
  base                                    : 0.000034
  false_ga_ue_de_nagai_kedo_func          : 0.000058
  true_ga_ue_de_mijikai_kedo_return_nashi : 0.012003
  false_ga_ue_de_nagai                    : 0.012866

Trial #2
  false_ga_ue_de_nagai_kedo_func          : 0.000030
  true_ga_ue_de_mijikai_kedo_return_ari   : 0.000031
  base                                    : 0.000035
  false_ga_ue_de_nagai                    : 0.011730
  true_ga_ue_de_mijikai_kedo_return_nashi : 0.012302

Trial #3
  base                                    : 0.000029
  false_ga_ue_de_nagai_kedo_func          : 0.000029
  true_ga_ue_de_mijikai_kedo_return_ari   : 0.000030
  true_ga_ue_de_mijikai_kedo_return_nashi : 0.011757
  false_ga_ue_de_nagai                    : 0.012152

「すぐにreturnした場合」と「関数に切り出した場合」は特に影響なさそうですが、
「returnがない場合」と「falseだけど長い」のは目に見えて遅くなっています。

多くの場合は気にするほどの速度差ではないのかもしれませんが、覚えておくといいことあるかも。