Konfekt / FastFold

Speed up Vim by updating folds only when called-for.
708 stars 24 forks source link

fastfold computes folds twice when integrated with vim-stay #43

Open anntzer opened 7 years ago

anntzer commented 7 years ago

After some profiling, it appears that when using vim-stay (perhaps loading views, in general -- haven't checked), the folds are recomputed twice -- once when the view script calls set fdl=..., and once when the view script calls zo for the first time. For slow folders, this makes quite a difference.

Konfekt commented 7 years ago

Thanks for the profiling. You are probably referring to the loading of a file in a buffer?

It is probably the autocmd

autocmd SessionLoadPost               * call s:UpdateWin(0)

in fastfold.vim. Does commenting it out fix the performance issue?

Then, this autocmd has its point, it might be that the foldmethod saved in a session is different from that set for a filetype, fired by the prior autocmd

autocmd BufWinEnter,FileType          * call s:UpdateWin(1)

Perhaps FastFold could be smarter about checking if the foldmethod did not change in-between those two autocmds.

anntzer commented 7 years ago

No, even with it commented my profile contains the following entry:

SCRIPT  /home/antony/.vim/view/<edited>
Sourced 1 time
Total time:   9.031140
 Self time:   0.045362

count  total (s)   self (s)
                            let s:so_save = &so | let s:siso_save = &siso | set so=0 siso=0
    1              0.000002 argglobal
    1   0.000008   0.000007 setlocal fdm=expr
    1              0.000006 setlocal fde=SimpylFold(v:lnum)
    1              0.000005 setlocal fmr={{{,}}}
    1              0.000004 setlocal fdi=#
    1   4.536047   0.022625 setlocal fdl=3
    1   0.000011   0.000010 setlocal fml=1
    1   0.000007   0.000006 setlocal fdn=20
    1              0.000005 setlocal fen
    1              0.000003 1866
    1   4.494608   0.022258 normal! zo
    1              0.000004 4589
    1              0.000082 normal! zo
    1              0.000002 4645
    1              0.000114 normal! zo
    1              0.000001 4801
    1              0.000077 normal! zo
    1              0.000007 let s:l = 2006 - ((28 * winheight(0) + 25) / 51)
    1              0.000003 if s:l < 1 | let s:l = 1 | endif
    1              0.000003 exe s:l
    1              0.000045 normal! zt
    1              0.000001 2006
    1              0.000045 normal! 0
    1   0.000017   0.000015 let &so = s:so_save | let &siso = s:siso_save
    1              0.000007 doautoall SessionLoadPost
                            " vim: set ft=vim :

Note again the two very slow calls to folding.

kopischke commented 7 years ago

After some profiling, it appears that when using vim-stay (perhaps loading views, in general -- haven't checked), the folds are recomputed twice.

By design, vim-stay should not interfere with fold computation and thus not affect load times except for the session loading proper. In fact, vim-stay limits the SessionLoadPost event to the current buffer (unlike regular view loading, which affects all buffers), so if anything, it should improve the situation compared to loadview. However, as “by design” and reality often tend to diverge wildly when it comes to software, I will follow this issue closely to see if anything needs to change on my end.

@anntzer could you also profile the whole thing without vim-stay and with a regular loadsession call instead? That might help @Konfekt isolate the issue.

kopischke commented 7 years ago

@anntzer have you been sourcing the view file directly to get that profile data? Because, when using vim-stay, that doautoall SessionLoadPost should actually be skipped.

EDIT: brain fart. Disregard the above.

anntzer commented 7 years ago

The profile data above was obtained simply by :e <file> with the profiler on. Manually sourcing the view file results in a similar profile.

kopischke commented 7 years ago

@anntzer yeah, forget my previous comment, brain not functioning properly yet – the call should be there, it’s just the event that should just be ignored…

Konfekt commented 7 years ago

The offending command, normal! zo is unmapped, therefore FastFold does not interfere. This would be the case if normal zo was fired, without !. Therefore it seems that the slowness comes simply from loading views, via Vim-Stay, but FastFold does not interfere. To check, please provide comparisons of the profile log with and without FastFold/VimStay.

That said, there is now a safeguard to avoid recomputing folds if neither buffer nor foldmethod changed, please give it a try.

anntzer commented 7 years ago

Now I have disabled all other plugins and it appears that directly loading the view is essentially instantaneous (possibly because vim doesn't update the folds in that case?). I am a bit confused, there is probably some bad interaction somewhere between plugins.

kopischke commented 7 years ago

@anntzer that is expected: without any plugin active, there is nothing reacting to the SessionLoadPost event fired during view load. Could you try disabling all plugins but vim-stay and FastFold, profile, then repeat the experience with just FastFold active?

anntzer commented 7 years ago

Can you list exactly what you want me to do in each condition? :e the file? :lo? Should I delete the view file at any point? That'll save a couple of cycles :)

kopischke commented 7 years ago

I’d suggest you profile:

  1. :e with only FastFold and vim-stay active
  2. :e with only FastFold active
  3. :e with only vim-stay active

which would allow us to compare the profile data (right, @Konfekt?). Using :lo would bypass stay entirely. EDIT: ensure there is a view file before profiling, and do not delete it in between tests.

anntzer commented 7 years ago

I set my vimrc (with vim -u /path/to/vimrc) to the minimal

set nocompatible
call plug#begin()
Plug 'tmhedberg/SimpylFold'
Plug 'Konfekt/FastFold'
Plug 'kopischke/vim-stay'
call plug#end()
filetype plugin on

and tried commenting out either plugin (the view file remains there). When vim-stay is active, folds simply do not get computed at all ("no fold found").

Any idea?

kopischke commented 7 years ago

Any idea?

Yes, two things:

  1. please leave your vimrc as is except for the plugins, then try profiling exactly as described in my previous comment. Folding is not on by default, hence no folds when testing with your minimal vimrc and without FastFold.
  2. what is tmhedberg/SimpylFold? Keeping it active while testing / profiling means introducing another potential source of issues with folding into the mix and makes it difficult to check if the issues are with either FastFold, vim-stay or a combination thereof.
anntzer commented 7 years ago

See attached.

tmhedberg/simpylfold is the folder I was using for python, but I removed it for this run. profile-fastfold-and-stay.txt profile-only-fastfold.txt profile-only-vimstay.txt

Konfekt commented 7 years ago

It seems all fine. With vim-stay, there's an addtional run of WinDo by FastFold after the session file is loaded, because it could have changed the fold(method).