Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git slows down Emacs to Death - How to Fix this?

Tags:

git

emacs

cygwin

Opening a file (either by typing Ctrl-x f, AKA Find File) or by typing f on that file in Dired mode), is painfully slow in working directories that have a .git subdirectory.

Even the simplest file (50 lines with mostly comments) could take up to 8 seconds to open.

The same file, in a different directory not managed by Git, opens in a jiffy, immediately.

Why is this happening and how can I fix this without disabling vc-mode? (since one of the main reasons I use Emacs is its M-x ediff-revision)

UPDATE 1: Thanks to @sanityinc's answer below, I ran ELP Profiling and this is what I received (for a very small file, 69 lines, 59 of which are plain comments):

Function Name                       Call Count   Elapsed Time  Average Time -------------                       ----------   ------------  ------------ vc-call-backend                      11          23.023        2.093 vc-find-file-hook                    1           8.757         8.757 vc-mode-line                         1           7.812         7.812 vc-default-mode-line-string          1           7.345         7.345 vc-state-refresh                     1           6.921         6.921 vc-state                             1           6.921         6.921 vc-default-state-heuristic           1           6.921         6.921 vc-registered                        1           0.945         0.945 vc-backend                           1           0.945         0.945 vc-git-registered                    1           0.912         0.912 vc-working-revision                  1           0.4240000000  0.4240000000 vc-find-root                         4           0.0990000000  0.0247500000 vconcat                              623         0.0220000000  3.53...e-005 vc-bzr-registered                    1           0.016         0.016 vc-check-master-templates            2           0.014         0.007 vc-default-registered                2           0.014         0.007 vc-rcs-registered                    1           0.008         0.008 vc-sccs-registered                   1           0.006         0.006 vc-svn-registered                    1           0.002         0.002 vc-cvs-registered                    1           0.001         0.001 vc-sccs-search-project-dir           1           0.0           0.0 vc-kill-buffer-hook                  6           0.0           0.0 vc-find-backend-function             11          0.0           0.0 vc-default-find-file-hook            1           0.0           0.0 vc-possible-master                   6           0.0           0.0 vc-file-clearprops                   1           0.0           0.0 vc-file-setprop                      3           0.0           0.0 vc-file-getprop                      5           0.0           0.0 vc-make-backend-sym                  15          0.0           0.0 

This is great information but I am not an Emacs/elisp expert, so how where do I go from here?

UPDATE 2: After putting this problem on the back burner for a while, I came across this great blog post: Cygwin slow start up: the culprit discovered! which essentially suggests starting bash completion in the background. I quickly implemented it and re-ran the ELP profiling test:

vc-call-backend                      11          14.489        1.317 vc-find-file-hook                    1           5.488         5.488 vc-mode-line                         1           5.118         5.118 vc-default-mode-line-string          1           4.719         4.719 vc-state-refresh                     1           4.282         4.282 vc-state                             1           4.282         4.282 vc-default-state-heuristic           1           4.282         4.282 vc-working-revision                  1           0.437         0.437 vc-registered                        1           0.37          0.37 vc-backend                           1           0.37          0.37 vc-git-registered                    1           0.34          0.34 vc-find-root                         4           0.088         0.022 vc-bzr-registered                    1           0.015         0.015 vc-check-master-templates            2           0.013         0.0065  vc-default-registered                2           0.013         0.0065  vc-rcs-registered                    1           0.007         0.007 vc-sccs-registered                   1           0.006         0.006 vc-cvs-registered                    1           0.001         0.001 vconcat                              623         0.001         1.60...e-006 vc-svn-registered                    1           0.001         0.001 vc-sccs-search-project-dir           1           0.0           0.0 vc-kill-buffer-hook                  6           0.0           0.0 vc-find-backend-function             11          0.0           0.0 vc-default-find-file-hook            1           0.0           0.0 vc-possible-master                   6           0.0           0.0 vc-file-clearprops                   1           0.0           0.0 vc-file-setprop                      3           0.0           0.0 vc-file-getprop                      5           0.0           0.0 vc-make-backend-sym                  15          0.0           0.0 

It's great to see vc-call-backend going down from 23 seconds to 14 seconds, but this is still unacceptable (finding a CVS-controlled file takes less than a split-second!).

UPDATE 3: Unable to solve the mystery, I tried my luck by upgrading to the latest cygwin (1.7.9-1). That didn't help.

So, I decided to try moving the sandbox (along with its .git subdirectory) from the Samba share to local storage (C:\Users\WinWin\Documents). I then re-ran the ELP profiling test:

vc-call-backend                           11          2.082         0.1892727272 vc-find-file-hook                         1           0.897         0.897 vc-git--call                              7           0.8929999999  0.1275714285 vc-git-mode-line-string                   1           0.78          0.78 vc-mode-line                              1           0.78          0.78 vc-default-mode-line-string               1           0.655         0.655 vc-git--out-ok                            5           0.6519999999  0.1304 vc-git-state                              1           0.53          0.53 vc-state-refresh                          1           0.53          0.53 vc-state                                  1           0.53          0.53 vc-default-state-heuristic                1           0.53          0.53 vc-git-working-revision                   2           0.25          0.125 vc-git-registered                         2           0.2239999999  0.1119999999 vc-git--run-command-string                1           0.18          0.18 vc-working-revision                       1           0.125         0.125 vc-registered                             1           0.1169999999  0.1169999999 vc-backend                                2           0.1169999999  0.0584999999 vc-git--empty-db-p                        1           0.11          0.11 vc-find-root                              3           0.003         0.001 vc-git-root                               2           0.002         0.001 vc-check-master-templates                 2           0.001         0.0005 vc-sccs-registered                        1           0.001         0.001 vc-default-registered                     2           0.001         0.0005 vc-bzr-registered                         1           0.001         0.001 vc-rcs-registered                         1           0.0           0.0 vc-sccs-search-project-dir                1           0.0           0.0 vc-kill-buffer-hook                       5           0.0           0.0 vc-default-find-file-hook                 1           0.0           0.0 vc-possible-master                        6           0.0           0.0 vc-cvs-registered                         1           0.0           0.0 vc-file-clearprops                        1           0.0           0.0 vc-file-setprop                           3           0.0           0.0 vc-file-getprop                           5           0.0           0.0 vc-svn-registered                         1           0.0           0.0 vc-make-backend-sym                       2           0.0           0.0 

Wow! That lowered vc-call-backend from 14 seconds to 2 seconds. This is great but not wonderful, because with Emacs/CVS I am able to visit a file in less than 35ms -- on the same Samba share where the sandbox originally resides:

vc-call-backend                           5           0.031         0.0062 vc-find-file-hook                         1           0.031         0.031 vc-registered                             1           0.031         0.031 vc-backend                                1           0.031         0.031 vc-rcs-registered                         1           0.016         0.016 vc-check-master-templates                 1           0.016         0.016 vc-default-registered                     1           0.016         0.016 vc-insert-file                            1           0.015         0.015 vc-cvs-get-entries                        1           0.015         0.015 vc-cvs-registered                         1           0.015         0.015 vc-cvs-state-heuristic                    1           0.0           0.0 vc-cvs-parse-sticky-tag                   1           0.0           0.0 vc-kill-buffer-hook                       1           0.0           0.0 vc-find-backend-function                  1           0.0           0.0 vc-cvs-parse-entry                        1           0.0           0.0 vc-mode-line                              1           0.0           0.0 vc-default-find-file-hook                 1           0.0           0.0 vc-possible-master                        3           0.0           0.0 vc-cvs-mode-line-string                   1           0.0           0.0 vc-default-mode-line-string               1           0.0           0.0 vc-state-refresh                          1           0.0           0.0 vc-working-revision                       1           0.0           0.0 vc-state                                  1           0.0           0.0 vc-file-clearprops                        1           0.0           0.0 vc-file-setprop                           5           0.0           0.0 vc-file-getprop                           7           0.0           0.0 vc-make-backend-sym                       2           0.0           0.0 

This raises 2 questions:

  1. What in the combination of git+cygwin makes it so sensitive to network speed?
  2. How can I make git go down to less than 50ms? After all, it is call "the fast version control system"

Update when using msysgit 1.7.8:

vc-call-backend                      11          0.626         0.0569090909 vc-find-file-hook                    1           0.281         0.281 vc-mode-line                         1           0.2189999999  0.2189999999 vc-default-mode-line-string          1           0.1879999999  0.1879999999 vc-state-refresh                     1           0.157         0.157 vc-state                             1           0.157         0.157 vc-default-state-heuristic           1           0.157         0.157 vc-registered                        1           0.062         0.062 vc-backend                           1           0.062         0.062 vc-git-registered                    1           0.062         0.062 vc-working-revision                  1           0.0310000000  0.0310000000 vc-rcs-registered                    1           0.0           0.0 vc-sccs-search-project-dir           1           0.0           0.0 vc-kill-buffer-hook                  6           0.0           0.0 vc-find-backend-function             11          0.0           0.0 vc-default-find-file-hook            1           0.0           0.0 vc-possible-master                   6           0.0           0.0 vc-check-master-templates            2           0.0           0.0 vc-cvs-registered                    1           0.0           0.0 vc-sccs-registered                   1           0.0           0.0 vc-file-clearprops                   1           0.0           0.0 vconcat                              623         0.0           0.0 vc-default-registered                2           0.0           0.0 vc-file-setprop                      3           0.0           0.0 vc-find-root                         4           0.0           0.0 vc-file-getprop                      5           0.0           0.0 vc-bzr-registered                    1           0.0           0.0 vc-svn-registered                    1           0.0           0.0 vc-make-backend-sym                  15          0.0           0.0 

Can you tell the difference? :)

Git under Emacs is way faster now, but it still much much slower than CVS under Emacs. So I have no idea why Git is called the "Fast Version Control System". It may be better than CVS, but faster?

like image 297
WinWin Avatar asked Jul 17 '11 14:07

WinWin


2 Answers

There's a built-in profiler called ELP. You can try something like M-x elp-instrument-package, enter "vc", and then try finding a file. Afterwards, M-x elp-results will show you a profile report.

(Note that if the time is instead being spent in non-vc-related functions, this technique will not show it, but you can instrument further packages if you like.)

like image 186
sanityinc Avatar answered Oct 02 '22 13:10

sanityinc


You can try to profile the opening of your file to see exactly what takes so much time.

like image 35
Francois G Avatar answered Oct 02 '22 14:10

Francois G