airblade / vim-gitgutter

A Vim plugin which shows git diff markers in the sign column and stages/previews/undoes hunks and partial hunks.
MIT License
8.35k stars 296 forks source link

Slow tab switching #82

Closed wmayner closed 10 years ago

wmayner commented 11 years ago

This plugin is awesome but causes Vim to switch tabs very slowly (~1 second).

I'm using the spf13 vim distribution. Let me know if there's any other info I can provide to determine the cause.


Vim version info:

IM - Vi IMproved 7.3 (2010 Aug 15, compiled Apr 9 2013 13:09:12) MacOS X (unix) version Included patches: 1-754 Compiled by will@terminus.home Huge version with MacVim GUI. Features included (+) or not (-): +arabic +autocmd +balloon_eval +browse ++builtin_terms +byte_offset +cindent +clientserver +clipboard +cmdline_compl +cmdline_hist +cmdline_info +comments +conceal +cryptv -cscope +cursorbind +cursorshape +dialog_con_gui +diff +digraphs +dnd -ebcdic +emacs_tags +eval +ex_extra +extra_search +farsi +file_in_path +find_in_path +float +folding -footer +fork() +fullscreen -gettext -hangul_input +iconv +insert_expand +jumplist +keymap +langmap +libcall +linebreak +lispindent +listcmds +localmap -lua +menu +mksession +modify_fname +mouse +mouseshape +mouse_dec -mouse_gpm -mouse_jsbterm +mouse_netterm +mouse_sgr -mouse_sysmouse +mouse_urxvt +mouse_xterm +multi_byte +multi_lang -mzscheme +netbeans_intg +odbeditor +path_extra +perl +persistent_undo +postscript +printer +profile +python -python3 +quickfix +reltime +rightleft +ruby +scrollbind +signs +smartindent -sniff +startuptime +statusline -sun_workshop +syntax +tag_binary +tag_old_static -tag_any_white +tcl +terminfo +termresponse +textobjects +title +toolbar +transparency +user_commands +vertsplit +virtualedit +visual +visualextra +viminfo +vreplace +wildignore +wildmenu +windows +writebackup -X11 -xfontset +xim -xsmp -xterm_clipboard -xterm_save system vimrc file: "$VIM/vimrc" user vimrc file: "$HOME/.vimrc" user exrc file: "$HOME/.exrc" system gvimrc file: "$VIM/gvimrc" user gvimrc file: "$HOME/.gvimrc" system menu file: "$VIMRUNTIME/menu.vim" fall-back for $VIM: "/Applications/MacVim.app/Contents/Resources/vim" Compilation: clang -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_MACVIM -Wall -Wno-unknown-pragmas -pipe -DMACOS_X_UNIX -no-cpp-precomp -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1 -I/System/Library/Frameworks/Tcl.framework/Headers -D_REENTRANT=1 -D_THREAD_SAFE=1 -D_DARWIN_C_SOURCE=1 Linking: clang -L. -L. -L/usr/local/lib -o Vim -framework Cocoa -framework Carbon -lncurses -liconv -framework Cocoa -fstack-protector -L/usr/local/lib -L/System/Library/Perl/5.12/darwin-thread-multi-2level/CORE -lperl -lm -lutil -lc -framework Python -F/System/Library/Frameworks -framework Tcl -framework CoreFoundation -framework Ruby

airblade commented 11 years ago

Sorry about that.

Have you set any vim-gitgutter configuration options at all?

Are you using the latest version of vim-gitgutter?

Is it always slow when switching tabs or only when you have many buffers? If the latter, please could you give me an idea of roughly how many buffers you have in the tab you're switching to, and how many buffers overall?

airblade commented 11 years ago

By the way I just simplified how to trade off accuracy for speed (1a13951).

wmayner commented 11 years ago

I tried setting g:gitgutter_eager=0 to no avail. Haven't touched any other vim-gitgutter configuration options. I am using the latest version via Vundle, and the slowdown occurs even with only two tabs and is no slower with many tabs.

airblade commented 11 years ago

It's puzzling that g:gitgutter_eager = 0 made no difference because it tells gitgutter only to run when you save a buffer (or read a file into a buffer). Switching tabs won't run gitgutter...unless you have set up Vim to write a buffer when you change tabs or something similar.

It might be useful to find out whether gitgutter is running when you switch tabs with g:gitgutter_eager = 0. You could add an echom "gitgutter: " . a:file at the top of the main function to verify whether or not gitgutter is running when you switch tabs.

Would it be possible to spin up your Vim with gitgutter as the only plugin? Then we could determine whether the problem is gitgutter alone or a dodgy interaction between gitgutter and another plugin.

wmayner commented 11 years ago

My mistake—setting g:gitgutter_eager=0 does fix the problem. Previously I'd tried setting it from command mode without effect, but this time I put it in my .vimrc and that did the trick. Adding the echo line shows that it is correctly not being called when switching buffers, though it's still slow when reading/writing from buffers.

I removed all other plugins except for GitGutter and Vundle, and the slow tab switching remains (when g:gitgutter_eager=1). Here's what happens when I open several buffers in tabs from the command line with mvim -p README.md Cakefile package.json test.sh wumpus_agents.py adjectives.txt clevertest.sh:

Screen Shot 2013-04-18 at 10 02 18 AM

airblade commented 11 years ago

The error message is pointing to redraw!. I don't know why that would cause an error. Stranger and stranger.

Also I'm surprised to see gitgutter running over README.md more than once. It looks like one run or more for each tab opened. Maybe mvim -p generates a TabEnter event for each tab it opens. I just checked and the same thing happens for me (without the error):

mvim -p README Gemfile Capfile Procfile Rakefile config.ru

Screen shot 2013-04-18 at 16 28 10

That's quite annoying.

However once all those tabs are open, switching tabs is fast. Does it remain slow for you?

airblade commented 11 years ago

There's definitely some weirdness going on here with the TabEnter events. I'll keeping looking into this...in the meantime please let me know if you find anything.

wmayner commented 11 years ago

Will do!

nemtsov commented 11 years ago

I'm having the same issue. It's reproduce it with :bn too, not just tabs. I ran a quick git bisect:

➜  vim-gitgutter git:(master) git bisect start
➜  vim-gitgutter git:(master) git bisect bad
➜  vim-gitgutter git:(master) git bisect good eec6b68

After a few repetitions of opening vim, loading the README.md in one buffer, and plugin/gitbuffer.vim in another and checking if it's slow, I ended up stopping on:

677dac451d19c71ac6e4e729565adff3b3002a4f is the first bad commit
commit 677dac451d19c71ac6e4e729565adff3b3002a4f
Author: Andy Stewart <boss@airbladesoftware.com>
Date:   Fri Mar 15 10:53:31 2013 +0100

    Add opt-out configuration for BufEnter and FocusGained.

My config:

git version 1.8.1.3
VIM - Vi IMproved 7.3 (2010 Aug 15, compiled Jun 20 2012 13:16:02)
Compiled by root@apple.com

Hope this helps.

airblade commented 11 years ago

@nemtsov Thanks for that. Which commit did you start from?

nemtsov commented 11 years ago

@airblade eec6b68 is the good commit I started with; being on the current master ff031d0.

gcapizzi commented 11 years ago

g:gitgutter_eager = 0 worked for me :+1:

vrybas commented 11 years ago

@airblade I'm autosaving buffers on all various events, so I set g:gitgutter_eager = 0 and just added execute 'GitGutterAll' to my autosave function. I've immediately experienced performance issues. For me the answer was to change GitGutterAll to GitGutter. Maybe that's a good idea to call GitGutter, instead of GitGutterAll when switching tabs? https://github.com/airblade/vim-gitgutter/commit/1a13951#L2R531

airblade commented 11 years ago

@vrybas GitGutterAll updates all the current tab's windows' buffers whereas GitGutter updates the current window's buffer only. On switching to a new tab we want all the visible windows to be up to date so we call GitGutterAll.

airblade commented 11 years ago

@wmayner @nemtsov Is this still a problem?

vrybas commented 11 years ago

@airblade,

On switching to a new tab we want all the visible windows to be up to date so we call GitGutterAll.

Yes, we surely want. But with a lot of opened windows (usually more than 4 for me) it is unacceptable slow. Speaking of my previous comment, I got rid of Autosave (partly because I switched from MacVim to vim inside Tmux), but I still call GitGutter on file save, rather then let it run eagerly.

The problem with this issue is that it blocks tabs switching right after you install GitGutter. Maybe just for a few folks, but still. Not cool.

I'd stay the section in FAQ about this behavior would help (here it is with all-out effort of my English skills)

wmayner commented 11 years ago

@airblade, g:gitgutter_eager = 0 worked, thanks!

nhooey commented 10 years ago

Running let g:gitgutter_eager=0 doesn't fix the slow tab switching problem.

In each one of my tabs I have a different lcd set, which is a different Git project. Would that affect the issue?

nhooey commented 10 years ago

I'm using MacVim installed from Homebrew on Mac OS.

vrybas commented 10 years ago

@nhooey I got this in my .vimrc

let g:gitgutter_eager = 0
let g:gitgutter_realtime = 0

Actually, I only update status manually

exe 'GitGutter'

Works best for me

nhooey commented 10 years ago

Adding let g:gitgutter_realtime = 0 makes no difference, it's still really slow on tab switching.

Ideally GitGutter should only be checking a file when it's actually reloaded or saved, not at any other time.

airblade commented 10 years ago

I started to investigate this and found Vim firing far more BufEnter and TabEnter events than I had expected. I think if I can figure out why the extra, unnecessary events are firing I'll be able to solve this problem.

Unfortunately I've been pretty busy recently so haven't found much time to make progress. Still, I want to fix it (not least because it affects me too).

nhooey commented 10 years ago

@airblade All I want for Christmas is for GitGutter tab-switching to be fast. ;)

airblade commented 10 years ago

@nhooey I've just pushed a change to speed things up. It doesn't specifically address tab-switching but it would be very helpful if you could let me know whether it solves the problem for you.

P.S. Ho ho ho :)

airblade commented 10 years ago

@nhooey As of d420a44 tab-switching should be fast. Please try it out and let me know what you think!

It turns out there are several different situations to consider:

The plugin does what it should in the first situation. In the second and third situations it updates the signs in the active buffer in the former tab before doing its thing in the new tab. This is due to a Vim weirdness which I haven't been able to workaround yet. However this single superfluous run doesn't slow things down much.

The one scenario which is still slow is opening tabs from the command line with vim -p file1 file2 .... I have sped this up somewhat, but due to the same Vim weirdness I can't get it as fast as it ought to be.

airblade commented 10 years ago

Closing this because it's fixed for me. Please let me know if it's still slow for you.

nhooey commented 10 years ago

Switching between tabs for me is still slow. The slowness is proportional to how many git-controlled files are in the destination tab.

However, it is slightly faster since updating with Vundle today.

I'm using MacVim 7.3 (66). What version of Vim are you using, @airblade?

airblade commented 10 years ago

@nhooey I think this may well be the problem: 7.3 is quite old now. I would expect upgrading to speed things up for you.

I'm on MacVim 7.4 (p1-22), i.e. snapshot 71. You've prompted me to upgrade to snapshot 72 ;)

Would you mind upgrading and letting me know how it works out?

airblade commented 10 years ago

@nhooey BTW if you only want vim-gitgutter to check a file when it's loaded or saved, add this to your vimrc:

let g:gitgutter_realtime = 0
let g:gitgutter_eager = 0

Having a different lcd in each tab shouldn't affect anything.

airblade commented 10 years ago

@nhooey At least one person found that Vundle wasn't correctly updating the plugin. You could try deleting the directory and then fresh-installing via Vundle to verify you really have got the latest version of vim-gitgutter.

nhooey commented 10 years ago

I just did rm -rf ~/.vim/bundle/vim-gitgutter, then reinstalled, sourced ~/.vim/bundle/vim-gitgutter/plugin/gitgutter.vim, disabled and enabled GitGutter, but the tab switching is still slow.

airblade commented 10 years ago

@nhooey Thanks for trying that; I'm trying to eliminate every possibility.

:profile start profile.log
:profile func *
:profile file *
" At this point do slow actions, i.e. switch tab
:profile pause
:noautocmd qall!
nhooey commented 10 years ago
airblade commented 10 years ago

@nhooey Many thanks. The profile's shown me two separate hotspots I can eliminate. I'll keep you posted.

airblade commented 10 years ago

@nhooey I've removed those two hotspots and it's faster for me. Please would you update and try again?

nhooey commented 10 years ago

Perfect! It's fast now.

nhooey commented 10 years ago

Thanks so much, @airblade.

airblade commented 10 years ago

@nhooey :beers:

nhooey commented 10 years ago

Sorry, @airblade, I was mistaken. I actually had GitGutter disabled so it appeared to be fast. I see no change from before.

I made a new profile.

airblade commented 10 years ago

@nhooey No worries. Thanks for the new profile – it shows you're using a pre-the-latest-improvement version (for example utility#is_tracked_by_git() doesn't exist any more). If you update the plugin it will (hopefully ;) go faster.

nhooey commented 10 years ago

Okay I coincidentally restarted Vim. Looks like even if you :BundleUpdate, then source your .vimrc, then source ~/.vim/bundle/vim-gitgutter/plugin/gitgutter.vim and disable/re-enable GitGutter, it still doesn't seem to load the latest version.

airblade commented 10 years ago

@gmarik Any ideas why Vundler wouldn't want to update to the latest version of vim-gitgutter? One or two others have run into this as well. And of course please let me know if I can modify vim-gitgutter somehow to make it collaborate better with Vundler. Thanks!

gmarik commented 10 years ago

@airblade ask if people they could provide a log output after :BundleInstall (by pressing l after it completes). There may be some errors preventing git from checking out latest updates.

airblade commented 10 years ago

@gmarik Much obliged!

zimski commented 9 years ago

hello, i have the same issue, but it's slow just for the :bp , ;bn is fast !!! Very strange

zimski commented 9 years ago

I solve the problem by using Ctrl instead of Leader !

tex commented 8 years ago

FYI: Very slow for me in Windows. Not using git, but clearcase. It is fast when I disabled gitgutter.

airblade commented 8 years ago

@tex This plugin only activates with git.

tex commented 8 years ago

I just described what I saw. The speed up was very noticeable. Perhaps it tests the git repository on each buf enter and this operation is perhaps very slow in Windows.

airblade commented 8 years ago

@tex Ok, thanks. On each BufEnter it runs this function to decide whether or not it should process the buffer. That function doesn't make any system() calls so it should be fast.

If that function returns truthy, which it generally will, gitgutter tries to run a diff. What happens if you do :echo system('git diff') when you're in one of your clearcase repos?