TaDaa / vimade

An eye friendly plugin that fades your inactive buffers and preserves your syntax highlighting!
MIT License
486 stars 8 forks source link

Switching windows is slow #35

Closed tbodt closed 4 years ago

tbodt commented 4 years ago

After installing Vimade I noticed that switching between windows became much slower. It used to be instant, but I've seen it take almost a second with vimade.

tbodt commented 4 years ago

Did a vim profile and all of the time was spent in a call to the neovim python remote. Ran py-spy and here's the result: vimade.svg.gz

TaDaa commented 4 years ago

Sounds abnormal -- some questions:

TaDaa commented 4 years ago

Think I found the cause -- added a fix to the word wrap logic. If your vimrc/init.vim is the one in your profile it should work now -- feel free to reopen if you still are having issues

tbodt commented 4 years ago

Thanks! Yes that is my vimrc, didn't think of just pointing you there. It's much faster now but not instant, though that's probably to be expected as half the screen needs to be redrawn.

tbodt commented 4 years ago

It now seems to be slow because of the IPC overhead involved in computing all these matchaddpos calls. A better solution would probably be to use 'winhighlight' and :ownsyntax.

TaDaa commented 4 years ago

There is definitely overhead in the ipc calls, although they should all be getting grouped together either by window or by line. matchaddpos is grouped per window when its needed, but let me know if you are seeing something different.

I do like the idea of winhighlight as a nvim only approach, it could reduce/remove a lot of the logic. I'm not quite sure what the performance difference would be, but could be an interesting experiment -- even nicer if vim implemented it as well.

tbodt commented 4 years ago

The matchaddpos calls are grouped together, but there's a bunch of IPC in a big loop before that which doesn't seem to be grouped. Here's a profile you can load into speedscope.app, generated by running a bit of vimscript to switch windows in an infinite loop. vimade.pyspy.gz

TaDaa commented 4 years ago

thanks -- going to reopen / will take a look as soon as I get a chance

TaDaa commented 4 years ago

cleaned up a bunch related to ipc + some additional optimizations for nvim. I think its looking overall much better.

I'm paying too much for string concat and some of the looping, so I'll probably try to reduce that later. After the current changes most of the performance cost is coming from synID which has always been the case on vim. There also may be some relevant alternatives to synID on nvim that I'll have to try out later as well

TaDaa commented 4 years ago

couple more updates -- performance wise nvim is now slightly ahead of vim -- seems to be some benefit for using command_output over other nvim eval functions, slight enough to give nvim the edge at least.

Had some ideas for winhighlight as you suggested. At the very least we can leverage winhighlight to generated Folded and other built-in highlights that should change per window/buffer as they become inactive as requested in #26 . We can currently determine the highlights linked to built-in highlights and skip them during the matchadd phase, but the benefit would be minimal (a few ms). If the neovim team were to fully support custom highlight replacement in winhighlight it could become the potential full approach for neovim. I'm open to other ideas here, I think winhighlight could potentially work as a solution but only in the scenario where all custom highlights link to built-in highlights.

The nvim docs also recommend using :ownsyntax for overriding custom highlights, but I think I would have to generate and override the existing syntax rules, which while is possible has other issues; I originally attempted parsing :syntax during my first attempt at this plugin (before release), but because "priority" is not captured in the output, it was not possible to accurately recreate the syntax rules. Alternatively I guess the entire syntax file could be parsed and colors replaced as a separate syntax, but I suspect that it is a whole other can of worms.

tbodt commented 4 years ago

Just updated to the latest Vimade, and it is indeed way faster. Thanks for working on this! There is of course still room for improvement, but I think it's now fast enough for me to use as a daily driver.

tbodt commented 4 years ago

As for the current state of things: I did a quick benchmark with this ex command:

:echom system("date") | let i = 0 | while i < 100 | wincmd j | wincmd k | let i += 1 | endwhile | echom system("date")

This took 4 seconds for 100 loops with two window switches per loop, which is 20ms per switch. That's perceptible but not a deal breaker. For comparison, the number is about 5ms per switch with Vimade disabled.

TaDaa commented 4 years ago

Nice -- thanks for your input and work as well! I'll be adding improvements at some point for moving the state comparisons into vimscript and grouping ipc per buffer per tick where possible. I'm hoping with tree-sitter looming for neovim, there may be significant performance gains soon?

Closing for now, but feel free to re-open if you bump into anything.