wsdjeg / vim-lua

lua development plugin for Vim
GNU General Public License v3.0
12 stars 3 forks source link

foldexpr causing extreme slowness #3

Open jyscao opened 5 years ago

jyscao commented 5 years ago

As previously mentioned in the chat some days ago, enabling the Lua layer, which includes this plugin makes working with Lua files very slow. Originally, I'd thought it was only caused by the inherent slow nature of using expr as the foldmethod, since it calls the function for every single line. However, after some more digging, it appears the function lua#fold#foldlevel(linenum) used to calculate the fold levels also contributes a great deal to the slowness.

I've profiled this again using the same file from before (~8kb, and now down to 306 lines total), to make sure the slowness indeed is related to the function used for foldexpr. First using the plugin as is, then by removing all the patterns (ex. do, function, end, etc.) used to check for folds. See results below.

Results using the plugin as provided:

SCRIPT  /home/jyscao/.cache/vimfiles/repos/github.com/wsdjeg/vim-lua/autoload/lua/fold.vim
Sourced 1 time
Total time:   0.000015
 Self time:   0.000015

count  total (s)   self (s)
    1              0.000004 function! lua#fold#foldlevel(linenum) abort
                                lua require('luavi').fold(require('luavi.vimutils').eval('a:linenum'))
                            endfunction

FUNCTION  lua#fold#foldlevel()
Called 612 times
Total time:  89.391175
 Self time:  89.391175

count  total (s)   self (s)
  612             89.389752     lua require('luavi').fold(require('luavi.vimutils').eval('a:linenum'))

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
  612  89.391175             lua#fold#foldlevel()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  612             89.391175  lua#fold#foldlevel()

Results with the local variable patterns in function fold_iter from lua/luavi.lua set to {}:

SCRIPT  /home/jyscao/.cache/vimfiles/repos/github.com/wsdjeg/vim-lua/autoload/lua/fold.vim
Sourced 1 time
Total time:   0.000016
 Self time:   0.000016

count  total (s)   self (s)
    1              0.000005 function! lua#fold#foldlevel(linenum) abort
                                lua require('luavi').fold(require('luavi.vimutils').eval('a:linenum'))
                            endfunction

FUNCTION  lua#fold#foldlevel()
Called 612 times
Total time:   6.255300
 Self time:   6.255300

count  total (s)   self (s)
  612              6.254650     lua require('luavi').fold(require('luavi.vimutils').eval('a:linenum'))

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
  612   6.255300             lua#fold#foldlevel()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  612              6.255300  lua#fold#foldlevel()

So as we can see, calling the foldexpr function 2x for every line of any given .lua file is definitely problematic in itself, since even after removing all the fold checking patterns, it still takes 6+ seconds to complete. But checking against all the patterns in fold_iter causes the delay to become dramatically worse, requiring 1.5min before the buffer is ready for use.

Before both causes of this slowness are fixed, I think it best to not use expr as the foldmethod for the Lua layer.

jyscao commented 5 years ago

I just created PR for a workaround to this issue.

Once you merge that PR, I will just add lua_foldmethod = "manual" in my SpaceVim's init.toml.

wsdjeg commented 5 years ago

this should be a layer option for lang#lua layer

jyscao commented 5 years ago

layer option added to lang#lua as advised (SpaceVim PR #3123)