pattern match vs subscript マイロクベンチマーク
ある値が ~[ で始まっているかをテストしたい時に、 zsh では、
$string == '~['* vs $string[1,2] == '~[' どっちが速い…もとい、“軽い”のか?
後者の方がコードのテキストの量は多いものの実際にはどうなのか、というところ。パターンマッチと、文字列を array subscript して切り出して比較するのとを比較してみたいです。
以下、ここで試してみたコード。
# > zsh --version # zsh 5.4.2 (x86_64-debian-linux-gnu) string="~[test test]" f () { [[ "$string" = '~['* ]] } g () { [[ "$string" = \~\[* ]] } h () { [[ "$string[1,2]" = '~[' ]] } # okp () { "$1" && echo ok } # okp f # okp g # okp h perf () { repeat 65535 "$1" } #perf "$1" ;# # > valgrind zsh -f perfmatchsubscript.zsh f 2>&1 |grep 'total heap' # ==767== total heap usage: 460,135 allocs, 459,063 frees, 20,618,468 bytes allocated # > valgrind zsh -f perfmatchsubscript.zsh g 2>&1 |grep 'total heap' # ==792== total heap usage: 460,135 allocs, 459,063 frees, 20,618,468 bytes allocated # > valgrind zsh -f perfmatchsubscript.zsh h 2>&1 |grep 'total heap' # ==810== total heap usage: 591,206 allocs, 590,133 frees, 58,366,788 bytes allocated #time (perf "$1") ;# # > repeat 10 zsh -f perfmatchsubscript.zsh f # ( perf "$1"; ) 0.86s user 0.30s system 107% cpu 1.083 total # ( perf "$1"; ) 0.86s user 0.25s system 108% cpu 1.028 total # ( perf "$1"; ) 0.76s user 0.33s system 109% cpu 0.999 total # ( perf "$1"; ) 0.77s user 0.33s system 108% cpu 1.012 total # ( perf "$1"; ) 0.78s user 0.27s system 111% cpu 0.945 total # ( perf "$1"; ) 0.82s user 0.30s system 108% cpu 1.029 total # ( perf "$1"; ) 0.80s user 0.32s system 107% cpu 1.034 total # ( perf "$1"; ) 0.80s user 0.28s system 108% cpu 0.991 total # ( perf "$1"; ) 0.77s user 0.30s system 107% cpu 0.998 total # ( perf "$1"; ) 0.78s user 0.26s system 106% cpu 0.972 total # > repeat 10 zsh -f perfmatchsubscript.zsh g # ( perf "$1"; ) 0.92s user 0.24s system 108% cpu 1.075 total # ( perf "$1"; ) 0.85s user 0.28s system 106% cpu 1.060 total # ( perf "$1"; ) 0.80s user 0.28s system 108% cpu 0.986 total # ( perf "$1"; ) 0.80s user 0.25s system 106% cpu 0.978 total # ( perf "$1"; ) 0.84s user 0.29s system 107% cpu 1.051 total # ( perf "$1"; ) 0.82s user 0.24s system 107% cpu 0.997 total # ( perf "$1"; ) 0.81s user 0.25s system 110% cpu 0.957 total # ( perf "$1"; ) 0.77s user 0.28s system 107% cpu 0.973 total # ( perf "$1"; ) 0.86s user 0.26s system 107% cpu 1.041 total # ( perf "$1"; ) 0.86s user 0.24s system 107% cpu 1.016 total # > repeat 10 zsh -f perfmatchsubscript.zsh h # ( perf "$1"; ) 1.02s user 0.31s system 108% cpu 1.231 total # ( perf "$1"; ) 0.99s user 0.24s system 109% cpu 1.121 total # ( perf "$1"; ) 0.92s user 0.23s system 109% cpu 1.053 total # ( perf "$1"; ) 0.96s user 0.28s system 111% cpu 1.111 total # ( perf "$1"; ) 0.93s user 0.27s system 107% cpu 1.102 total # ( perf "$1"; ) 0.95s user 0.28s system 107% cpu 1.143 total # ( perf "$1"; ) 0.94s user 0.22s system 106% cpu 1.090 total # ( perf "$1"; ) 0.97s user 0.22s system 108% cpu 1.089 total # ( perf "$1"; ) 0.98s user 0.34s system 107% cpu 1.225 total # ( perf "$1"; ) 0.83s user 0.31s system 107% cpu 1.065 total
この場合、パターンマッチの方が、メモリアロケーションも少なくて済み、速度も速いという結果になりました。微妙な差だけれども。(それも、実際にはありえないような repeat 65535 … です、あしからずという。)
このコードは、ファイルの入力補完に使われるコードの中、多分一回は呼ばれるようになる箇所で使いたいと思っていて、両者の違いはそんなに問題にならないと思っています。