【问题标题】:Vim macro very slowVim 宏很慢
【发布时间】:2012-01-12 22:10:28
【问题描述】:

我将一个非常简单的 vim 宏保存到一个键中:qa$pjq,然后使用 40000@a 执行 40000 次。这很慢。我一定做错了什么,因为虽然它确实有效,但它需要大约 60-90 秒。这和vim一样快吗?是否有一些设置可以加速这一点?是否存在使宏执行变慢的插件组合?

我正在使用 Mac 并使用 MacVim。这是一个纯文本文件,真的没有比这更简单的了。

【问题讨论】:

    标签: vim text


    【解决方案1】:

    原因

    然后用 40000@a 执行 40000 次。这是非常缓慢的。我一定是做错了什么,因为虽然它确实有效,但它需要大约 60-90 秒。

    其他答案均未针对主要原因。宏运行缓慢主要受插件影响粘贴,而不是屏幕重绘。

    filetype 语法和lazyredraw 只会产生非常、非常、非常最小的影响。正确的解决方案应该是找出并禁用那些在插入模式下减慢编辑速度的插件。

    宏只是将存储在寄存器中的动作重播到所选区域。运行宏的环境和你录制宏的环境是一样的。插件可能会在编辑过程中引入额外的成本。通常这不是问题。但将成本乘以 40,000 会显着放大影响。

    这是我得到的对宏运行的影响因子:

    system clipboard >> plugins >> filetype, syntax
    

    解决方案

    系统剪贴板

    避免在宏中访问系统剪贴板

    与访问内部寄存器相比,访问外部系统剪贴板+* 会带来额外的成本。它甚至可能永远冻结宏重播(在我的测试中运行 6000 行宏)。

    imap 和事件

    禁用影响编辑速度的插件

    • 那些插入映射,例如imap <CR> <Tab> ...
      • jiangmiao/auto-pairs
      • Raimondi/delimitMate
      • ...
    • :noautocmd :norm @q 在宏运行期间暂时禁用事件。 或者在宏运行之前set eventignore=all,之后再设置。
    • ~~那些和编辑相关的注册钩子~~(好像不需要)
      • 相关挂钩
        • CursorMoved(I), CursorHold(I)
        • InsertCharPre, InsertEnter, InsertLeave(Pre)
      • neoclide/coc.nvim
      • brglng/vim-im-select
      • chrisbra/Colorizer
      • ...

    注意

    • 并非所有在上述钩子上注册函数的插件都会产生很大的不同 关于宏运行速度。其中一些只对微不足道的、微不足道的影响 编辑速度。您必须通过使用和不使用宏来找到它们 插件并比较时间成本。
    • 无法完全禁用来自auto-pairs 的插入模式映射, 这也是我切换到delimitMate 的原因之一。
    • 在选择时使用:noautocmd。范围应放在norm 之前::noa '<,'>norm! @q

    这是我在运行宏之前禁用上述插件的切换功能。

    使用<F3>m 在录制宏之前禁用插件。运行宏后, <F3>m 再次重置这些插件的状态。 (我把我所有的切换都归为<F3>m 代表宏。您可以根据需要调整映射。)

    function! <SID>ToggleMacro(...)
      " Optimize macro running by disable some plugins.
      if get(g:, '_macro', {}) ==# {}
        let g:_macro = {'state': 1}
    
        let g:_macro.auto_pairs = get(b:, 'autopairs_enabled')
        if g:_macro.auto_pairs
          let b:autopairs_enabled = 0
        endif
    
        let g:_macro.delimit_mate = get(b:, 'delimitMate_enabled')
        if g:_macro.delimit_mate
          DelimitMateOff
        endif
    
        let g:_macro.eventignore = &eventignore
        set eventignore=all
    
      else
        let g:_macro.state = 0
    
        let b:autopairs_enabled = g:_macro.auto_pairs
    
        if g:_macro.delimit_mate
          DelimitMateOn
        endif
    
        let &eventignore = g:_macro.eventignore
    
      endif
    
      if g:_macro.state
        echo 'Macro boost: On'
      else
        echo 'Macro boost: Off'
        unlet g:_macro
      endif
    endfunction
    
    nnoremap <F3>m  :call <SID>ToggleMacro()<CR>
    command! -nargs=? ToggleMacro call <SID>ToggleMacro(<f-args>)
    

    参考

    • :h autocmd, :h noautocmd, :h eventignore
    • 感谢Christian Brabandt提及:noautocmdeventignore

    【讨论】:

      【解决方案2】:

      我遇到了一些问题,即即使在少量行上操作时,VIM 宏也很慢(尽管更改很复杂)。 se synmaxcol=1se ft=txtse foldmethod=manual 可以提供很多帮助。 VIM 似乎不够聪明,无法等到宏完成后才更新语法高亮和折叠以及其他此类更改。老实说,这是 VIM 的失败。

      【讨论】:

      • 没错,语法高亮确实会影响宏重放时间。 set syntax= 在我的情况下帮助了我。
      【解决方案3】:

      我建议使用 'vim -u NONE' 启动一个空白 vim。 通常插件会减慢速度。 您会看到它以这种方式运行得更快。 然后你需要找出是什么插件导致了这种减速。 另见How to see which plugins are making Vim slow?

      【讨论】:

      • 闪电般的快!
      【解决方案4】:

      粘贴 40,000 行并不需要很长时间,但是如果您像经常在减慢速度的宏中那样让屏幕不断更新。

      首先,关于您的宏应该做什么的问题。如果只是粘贴默认寄存器的内容,那么正确的宏定义就是qapjq。无需将光标定位在前一行的特定位置。 [编辑:对不起,我假设您正在执行逐行粘贴,如果您在行尾粘贴逐字符寄存器,则需要定位。 . ..]

      其次,您可以通过设置lazyredraw (:set lazyredraw) 来加速您当前的宏,因此屏幕不会随其更新。可能不会大大加快速度,像这样的键盘宏不像直接处理缓冲区。

      第三,这是另一种需要大约一秒钟的方法: .,+40000g/.*/normal! $p

      【讨论】:

      • 他没有进入插入模式,只是将宏存储在寄存器a中。不过,屏幕更新很好。
      • @Don:哎呀,谢谢。然后我的意思是没有必要让 $ 走到行尾。如果他将字符粘贴到行尾,这可能是错误的。 . .
      • 哇;这是运行在大文件上的长宏的救命稻草!时间差快了一个数量级。
      【解决方案5】:

      这是正常的。正如 Herbert Sitz 所写,更新屏幕很慢。

      您可能只想运行一个替换命令::.,+40000s/.*/&amp;&lt;c-r&gt;"

      • .,+40000 是一个范围,包括当前行和后面的 40000 行
      • 模式中的.* 匹配整行
      • 字符串中的&amp; 是匹配的行
      • &lt;c-r&gt;"粘贴未命名寄存器的内容

      【讨论】:

        猜你喜欢
        • 2012-03-09
        • 1970-01-01
        • 2017-05-08
        • 1970-01-01
        • 2011-06-12
        • 2013-05-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多