chentoast / marks.nvim

A better user experience for viewing and interacting with Vim marks.
MIT License
892 stars 47 forks source link

High CPU usage in neovim #62

Open DOhlsson opened 2 years ago

DOhlsson commented 2 years ago

First of all, thank you for making this plugin, I find it quite useful.

However, since installing this plugin my neovim has increased in CPU usage by quite a lot, even when idle. A fresh neovim with zero files open uses around 1-2% constantly and after having opened a bunch of projects and working for a while it can use as much as 20% CPU when the window is unfocused and idle.

I did some profiling and noticed that the CPU usage is caused by airline calling fugitive to get the git branch over and over. But I do not believe airline is the culprit. If I disable marks.nvim the behavior disappears, so it appears that marks is causing airline to redraw and refresh the information displayed. I don't know how to profile lua in neovim so I have not been able to find the smoking gun.

Neovim version 0.6.1 marks.nvim latest commit from master (8e80a20) vim-airline latest commit from master (be5bda1)

Profiling for 1 minute with only an empty buffer open and marks installed.

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
  459   1.493836   0.044120  airline#extensions#branch#get_head()
  459   1.404939   0.035711  airline#extensions#branch#head()
  459   1.349817   0.068232  <SNR>50_update_branch()
  459   1.205509   0.072975  <SNR>50_update_git_branch()
  459   1.083190   0.048279  FugitiveHead()
  459   0.711723   0.071026  fugitive#Head()
  459   0.640698   0.295998  fugitive#Find()
 2295   0.567162   0.269648  FugitiveGitDir()
  459   0.283230   0.179159  FugitiveExtractGitDir()
  459   0.268719   0.175062  airline#check_mode()
  459   0.196069   0.154334  airline#extensions#whitespace#check()
 1836   0.160592   0.102935  airline#util#shorten()
  918   0.142871   0.016757  <SNR>63_GitDir()
 4131   0.104678   0.090930  airline#util#wrap()
 3213   0.103147             airline#util#append()
 3221   0.100379             airline#util#winwidth()
  459   0.099443   0.008611  <SNR>63_Tree()
    3   0.091694   0.015135  airline#highlighter#highlight()
  459   0.090832   0.017036  FugitiveWorkTree()
  459   0.077679   0.020470  FugitiveCommonDir()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  459   0.640698   0.295998  fugitive#Find()
 2295   0.567162   0.269648  FugitiveGitDir()
  459   0.283230   0.179159  FugitiveExtractGitDir()
  459   0.268719   0.175062  airline#check_mode()
  459   0.196069   0.154334  airline#extensions#whitespace#check()
 3213              0.103147  airline#util#append()
 1836   0.160592   0.102935  airline#util#shorten()
 3221              0.100379  airline#util#winwidth()
 4131   0.104678   0.090930  airline#util#wrap()
  459   1.205509   0.072975  <SNR>50_update_git_branch()
  459   0.711723   0.071026  fugitive#Head()
  918              0.068637  airline#extensions#coc#get()
  459   1.349817   0.068232  <SNR>50_update_branch()
  459   0.076076   0.064966  <SNR>50_update_hg_branch()
  459   0.059347   0.053924  airline#extensions#fugitiveline#bufname()
  459   1.083190   0.048279  FugitiveHead()
  459   0.048988   0.045174  <SNR>21_CeilingDirectories()
  459   1.493836   0.044120  airline#extensions#branch#get_head()
  459   1.404939   0.035711  airline#extensions#branch#head()
 1377              0.032395  airline#util#prepend()

Profiling for 1 minute with only an empty buffer open and marks installed and refresh_interval set to 1000.

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
  147   0.414216   0.013844  airline#extensions#branch#get_head()
  147   0.386796   0.011314  airline#extensions#branch#head()
  147   0.337155   0.021011  <SNR>51_update_branch()
  147   0.292153   0.022483  <SNR>51_update_git_branch()
  147   0.254209   0.014516  FugitiveHead()
  147   0.223498   0.023268  fugitive#Head()
  147   0.200230   0.092100  fugitive#Find()
  147   0.143204   0.051988  airline#check_mode()
  735   0.092834   0.088482  FugitiveGitDir()
    3   0.089130   0.014449  airline#highlighter#highlight()
  112   0.063128   0.015348  airline#highlighter#exec()
  147   0.059178   0.047602  airline#extensions#whitespace#check()
  588   0.046841   0.029527  airline#util#shorten()
  294   0.044657   0.005488  <SNR>64_GitDir()
  180   0.044592   0.019472  airline#highlighter#get_highlight()
  147   0.038218   0.032765  <SNR>51_update_untracked()
   28   0.034233   0.002599  <SNR>50_exec_separator()
 1323   0.031572   0.027515  airline#util#wrap()
 1029   0.031102             airline#util#append()
  147   0.030942   0.002637  <SNR>64_Tree()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  147   0.200230   0.092100  fugitive#Find()
  735   0.092834   0.088482  FugitiveGitDir()
  147   0.143204   0.051988  airline#check_mode()
  147   0.059178   0.047602  airline#extensions#whitespace#check()
  147   0.038218   0.032765  <SNR>51_update_untracked()
 1029              0.031102  airline#util#append()
 1037              0.030141  airline#util#winwidth()
  588   0.046841   0.029527  airline#util#shorten()
 1323   0.031572   0.027515  airline#util#wrap()
  147   0.223498   0.023268  fugitive#Head()
  147   0.292153   0.022483  <SNR>51_update_git_branch()
  360              0.022218  <SNR>50_get_syn()
  294              0.021206  airline#extensions#coc#get()
  147   0.337155   0.021011  <SNR>51_update_branch()
  147   0.023991   0.020658  <SNR>51_update_hg_branch()
  180   0.044592   0.019472  airline#highlighter#get_highlight()
  147   0.018487   0.016851  airline#extensions#fugitiveline#bufname()
  112   0.063128   0.015348  airline#highlighter#exec()
  147   0.254209   0.014516  FugitiveHead()
    3   0.089130   0.014449  airline#highlighter#highlight()

Profiling for 1 minute with only an empty buffer open and marks not installed.

FUNCTIONS SORTED ON TOTAL TIME
count  total (s)   self (s)  function
   11   0.193089   0.004407  airline#check_mode()
    5   0.184608   0.029884  airline#highlighter#highlight()
  182   0.130496   0.031651  airline#highlighter#exec()
  278   0.088883   0.039066  airline#highlighter#get_highlight()
   42   0.065336   0.004849  <SNR>48_exec_separator()
  556   0.043859             <SNR>48_get_syn()
   11   0.034260   0.000990  airline#extensions#branch#get_head()
   11   0.032236   0.001246  airline#extensions#branch#head()
   11   0.030377   0.001519  <SNR>49_update_branch()
   84   0.028473   0.001927  airline#themes#get_highlight()
   11   0.027116   0.001634  <SNR>49_update_git_branch()
   11   0.024320   0.001109  FugitiveHead()
    1   0.023731   0.000047  <SNR>15_on_focus_gained()
    1   0.023653   0.000136  <SNR>15_airline_refresh()
    1   0.023372   0.000156  airline#update_statusline()
   72   0.023042             <SNR>48_GetHiCmd()
    1   0.022970   0.000109  <SNR>44_invoke_funcrefs()
    1   0.018806   0.002543  12()
   11   0.016250   0.001710  fugitive#Head()
   11   0.014540   0.006655  fugitive#Find()

FUNCTIONS SORTED ON SELF TIME
count  total (s)   self (s)  function
  556              0.043859  <SNR>48_get_syn()
  278   0.088883   0.039066  airline#highlighter#get_highlight()
  182   0.130496   0.031651  airline#highlighter#exec()
    5   0.184608   0.029884  airline#highlighter#highlight()
   72              0.023042  <SNR>48_GetHiCmd()
  182              0.013469  <SNR>48_CheckDefined()
   11   0.014540   0.006655  fugitive#Find()
   55   0.012555   0.006103  FugitiveGitDir()
  278              0.005958  <SNR>48_get_array()
   42   0.065336   0.004849  <SNR>48_exec_separator()
   11   0.193089   0.004407  airline#check_mode()
   11   0.006118   0.003811  FugitiveExtractGitDir()
   11   0.004497   0.003580  airline#extensions#whitespace#check()
  110              0.003518  <SNR>48_hl_group_exists()
  135              0.003200  <SNR>48_group_not_done()
    1   0.018806   0.002543  12()
   85              0.002524  airline#util#winwidth()
   77              0.002343  airline#util#append()
   44   0.003607   0.002322  airline#util#shorten()
   99   0.002375   0.002066  airline#util#wrap()
chentoast commented 2 years ago

I am almost certain that this is a bug in neovim core - ref https://github.com/neovim/neovim/issues/14303. In general, there are a number of bad interactions with timers and the underlying neovim event loop - for a workaround, please see what I posted in #40. In the future, I may consider moving redraw logic to use CursorHold autocommands instead of timers, due to these bad interactions.

Thanatermesis commented 1 year ago

I have also this issue, any news about it? Unfortunately I love this plugin but I will need to disable it for now 🤔

vanaigr commented 7 months ago

I believe this is caused by Bookmarks:refresh() deleting and re-adding the bookmark signs:

https://github.com/chentoast/marks.nvim/blob/93b4fd249ec1cb9d0810e4e7263532ab31fdba29/lua/marks/bookmark.lua#L210-L218

This decoration provider can be used to see when screen redraws are happening:

 local redraw = 0
 local ns = vim.api.nvim_create_namespace('MarksIssue62')
 vim.api.nvim_set_decoration_provider(ns, {
     on_start = function()
         print(redraw)
         redraw = redraw + 1
     end
 })

Currently it would print a new number every refresh_interval. Removing the call to Bookmarks:refresh() from refresh() stops this.

vanaigr commented 7 months ago

The problem was in vim.fn.sign_unplace(), which was causing redraw even when the buffer does not contain bookmarks. This is fixed in neovim/neovim@c4afb9788c4f139eb2e3b7aa4d6a6a20b67ba156. Though this wouldn't help if the buffer actually contains bookmarks.