统计每个Vim插件花费的启动时间

2018-08-07|Categories: awk-sed-grep, Linux, Vim|

生成Vim启动日志

vim --startuptime ~/vim_startup.log

vim --help | grep startuptime
   --startuptime <file> Write startup timing messages to <file>

查看启动日志中与插件相关的内容

启动日志既包含了Vim内置功能的启动信息,也包含了所有插件的启动信息,这里我们只关注插件对启动过程的影响,因此首先需要筛选出与插件相关的记录:

head -n6 vim_startup.log; grep '.vim/plugged' vim_startup.log | sort -k5 | head


times in msec
 clock   self+sourced   self:  sourced script
 clock   elapsed:              other lines

057.891  000.116  000.116: sourcing /root/.vim/plugged/ale/autoload/ale/events.vim
147.811  000.071  000.071: sourcing /root/.vim/plugged/ale/autoload/ale/statusline.vim
128.653  000.248  000.248: sourcing /root/.vim/plugged/ale/autoload/ale.vim
058.311  001.320  001.204: sourcing /root/.vim/plugged/ale/plugin/ale.vim
056.342  000.249  000.249: sourcing /root/.vim/plugged/ctrlp.vim/autoload/ctrlp/mrufiles.vim
056.745  001.028  000.779: sourcing /root/.vim/plugged/ctrlp.vim/plugin/ctrlp.vim
041.623  000.499  000.499: sourcing /root/.vim/plugged/delimitmate/autoload/delimitMate.vim
043.945  003.380  002.881: sourcing /root/.vim/plugged/delimitmate/plugin/delimitMate.vim
038.921  000.076  000.076: sourcing /root/.vim/plugged/deoplete.nvim/plugin/deoplete.vim
071.664  002.171  002.171: sourcing /root/.vim/plugged/emmet-vim/plugin/emmet.vim

可以看到,第二列(用空格分隔)是self+sourced总共花费的时间,单位是毫秒,最后一列就是对应的被执行的插件脚本,而且一个插件通常有多个脚本需要被执行。我们需要提取这两列数据用于统计。

这里的.vim/plugged表示所有插件使用Vim-plug插件管理器来管理。

用awk脚本分析启动日志

Vim启动过程中耗时最长的10个插件:

awk -F'[ /]' '/\.vim\/plugged/ {print $3,$11}' vim_startup.log | \
awk '{plug[$2]++; time[$2]+=$1} END {for (i in plug) {printf "%30s %10.3f ms\n", i, time[i] | "sort -k2nr | head"}}'
                vim-easymotion      6.415 ms
                   vim-airline      4.210 ms
                   delimitmate      3.879 ms
                  vim-polyglot      3.342 ms
         vim-textobj-parameter      3.056 ms
              vim-textobj-path      2.651 ms
                      fencview      2.566 ms
                     emmet-vim      2.171 ms
                           ale      1.755 ms
               vim-textobj-uri      1.572 ms

在这个awk脚本中,-F'[ /]'表示把分隔符设置为空格和斜线,把斜线作为分隔符是为了便于从插件脚本路径中提取插件名称。而只要分隔符不是默认值(空格),字段(列)前面的空格和制表符就不会被丢弃,也就是说,如果字段(列)前面的空格、制表符、用户指定的分隔符(这里就是斜线/)多于一个,那么多出来的每一个空格、制表符、用户指定的分隔符都会被当做一个字段。

而在生成的启动日志中,肉眼看到的前三列数字之间其实都是被两个空格(详见下方输出中的sp)分隔,对于当前脚本中的awk来说,多出来的空格都会被当成字段(列),因此,符合我们需求的字段就是print $3,$11

awk -F'[ /]' '/\.vim\/plugged/ {print $0 | "head -n1"}' vim_startup.log | od -abc
0000000   0   2   5   .   0   4   6  sp  sp   0   0   0   .   0   3   2
        060 062 065 056 060 064 066 040 040 060 060 060 056 060 063 062
          0   2   5   .   0   4   6           0   0   0   .   0   3   2
0000020  sp  sp   0   0   0   .   0   3   2   :  sp   s   o   u   r   c
        040 040 060 060 060 056 060 063 062 072 040 163 157 165 162 143
                  0   0   0   .   0   3   2   :       s   o   u   r   c
0000040   i   n   g  sp   /   r   o   o   t   /   .   v   i   m   /   p
        151 156 147 040 057 162 157 157 164 057 056 166 151 155 057 160
          i   n   g       /   r   o   o   t   /   .   v   i   m   /   p
0000060   l   u   g   g   e   d   /   u   l   t   i   s   n   i   p   s
        154 165 147 147 145 144 057 165 154 164 151 163 156 151 160 163
          l   u   g   g   e   d   /   u   l   t   i   s   n   i   p   s
0000100   /   f   t   d   e   t   e   c   t   /   s   n   i   p   p   e
        057 146 164 144 145 164 145 143 164 057 163 156 151 160 160 145
          /   f   t   d   e   t   e   c   t   /   s   n   i   p   p   e
0000120   t   s   .   v   i   m  nl
        164 163 056 166 151 155 012
          t   s   .   v   i   m  \n
0000127

筛选出来的字段然后管道(|)给第二个awk脚本进行计算,然后排序,最终打印前十个结果。

以上脚本适合root用户,非root用户需要稍作调整,把$11改为$12,因为插件脚本路径会是/home/username/.vim/plugged/ale/autoload/ale.vim,其中的家目录/home/username相比root用户的/root多了一层。

# for non-root users

awk -F'[ /]' '/\.vim\/plugged/ {print $3,$12}' vim_startup.log | \
awk '{plug[$2]++; time[$2]+=$1} END {for (i in plug) {printf "%30s %10.3f ms\n", i, time[i] | "sort -k2nr | head"}}'

Leave A Comment