Git замедляет Emacs to Death - как это исправить? - PullRequest
33 голосов
/ 17 июля 2011

Открытие файла (набрав Ctrl-x f, AKA Find File) или набрав f для этого файла в режиме Dired), мучительно медленно в рабочих каталогах, имеющих подкаталог .git.

Даже самый простой файл (50 строк с в основном комментариями) может занять до 8 секунд .

Тот же файл в другом каталоге, не управляемом Git,открывается в один миг, немедленно.

Почему это происходит и как я могу исправить это без , отключив vc-режим?(поскольку одной из основных причин, по которой я использую Emacs, является его M-x ediff-revision)

ОБНОВЛЕНИЕ 1: Благодаря ответу @ sanityinc, приведенному ниже, я запустил ELP Profiling, и вот что я получил (дляочень маленький файл, 69 строк, 59 из которых являются простыми комментариями):

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

Это отличная информация, но я не эксперт по Emacs / elisp, так как же мне отсюда пойти?

ОБНОВЛЕНИЕ 2: После некоторого откладывания этой проблемы на некоторое время я натолкнулся на эту замечательную запись в блоге: Медленный запуск Cygwin: преступник обнаружен! , что по сутипредлагает начать завершение bash в фоновом режиме.Я быстро реализовал его и повторно запустил тест профилирования ELP:

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

Здорово видеть, как vc-call-backend снижается с 23 секунд до 14 секунд, но это все еще неприемлемо (поиск файла, управляемого CVS)занимает меньше доли секунды!).

ОБНОВЛЕНИЕ 3: Не удалось разгадать тайну, я попытал счастья, обновившись до последней версии Cygwin (1.7.9-1).Это не помогло.

Итак, я решил попробовать переместить песочницу (вместе с ее подкаталогом .git) из общего ресурса Samba в локальное хранилище (C:\Users\WinWin\Documents).Затем я повторно запустил тест профилирования ELP:

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

Ух ты!Это понизило vc-call-backend с 14 до 2 секунд.Это здорово, но не замечательно, потому что с Emacs / CVS я могу посетить файл в менее 35 мс - в том же общем ресурсе Samba, где изначально находится песочница:

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

Возникает 2 вопроса:

  1. Что в сочетании с git + cygwin делает его настолько чувствительным к скорости сети?
  2. Как заставить git отключитьсяменее 50 мс?В конце концов, это называется « fast система контроля версий»

Обновление при использовании 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

Можете ли вы сказать разницу?:)

Git в Emacs теперь работает намного быстрее, но все еще намного медленнее, чем CVS в Emacs.Так что я понятия не имею, почему Git называется «Система быстрого контроля версий».Может быть лучше, чем CVS, но быстрее?

Ответы [ 4 ]

43 голосов
/ 18 июля 2011

Есть встроенный профилировщик, который называется ELP. Вы можете попробовать что-то вроде M-x elp-instrument-package, ввести «vc», а затем попробуйте найти файл. После этого M-x elp-results покажет вам отчет профиля.

(Обратите внимание, что если вместо этого время тратится на функции, не связанные с vc, этот метод не покажет его, но при желании вы можете использовать дополнительные пакеты.)

4 голосов
/ 18 июля 2011

Вы можете попробовать профиль открытия вашего файла, чтобы точно узнать, что занимает столько времени.

2 голосов
/ 23 февраля 2017

У меня была такая же проблема с использованием windows git 2.10 из mingw emacs 25.1.1.

Для проверки используется следующее:

(progn
  ;; make sure the buffer is not already open
  (elp-instrument-function 'find-file-other-window)
  (elp-instrument-function 'vc-git-registered)
  (elp-instrument-function 'vc-git-mode-line-string)
  (elp-instrument-function 'vc-git-find-file-hook)
  (find-file-other-window "my-file-in-a-git-repo")
  (elp-results)
  (elp-restore-all))

дал следующий профиль:

find-file-other-window   1           1.1076142     1.1076142
vc-git-mode-line-string  1           0.6396082     0.6396082
vc-git-find-file-hook    1           0.2652034     0.2652034
vc-git-registered        1           0.1872024     0.1872024

Функция vc-git-mode-line-string занимает некоторое время. Это показывает что-то вроде Git:mybranch в строке режима вашего окна. Мне все равно, что каждый раз ждать его, поэтому я перезаписываю реализацию, просто возвращая "Git":

(defun vc-git-mode-line-string (file)
  "Overwritten default vc-git-el implementation. Return a string
for `vc-mode-line' to put in the mode line for FILE."
  "Git")

Функция vc-git-find-file-hook откроет симпатичный режим редактирования конфликтов, если вы открываете конфликтующий файл. Реализация сначала вызывала vc-git-conflicted-files, что занимает некоторое время, а затем выполняла довольно тривиальную проверку, начинаются ли строки с <<<<<<<. Я просто поменял их местами, и теперь реализация занимает в большинстве случаев около 0,0 секунд.

(defun vc-git-find-file-hook ()
  "Overwritten default vc-git-el implementation. Activate
`smerge-mode' if there is a conflict."
  (when (and buffer-file-name
             ;; FIRST check whether this file looks like a conflicted file
             (save-excursion
               (goto-char (point-min))
               (re-search-forward "^<<<<<<< " nil 'noerror))
             ;; THEN ask git if it really is a conflict
             (vc-git-conflicted-files buffer-file-name))
    (vc-file-setprop buffer-file-name 'vc-state 'conflict)
    (smerge-start-session)
    (when vc-git-resolve-conflicts
      (add-hook 'after-save-hook 'vc-git-resolve-when-done nil 'local))
    (vc-message-unresolved-conflicts buffer-file-name)))

Результаты:

find-file-other-window   1           0.2838039     0.2838039
vc-git-registered        1           0.2682037     0.2682037
vc-git-find-file-hook    1           0.0           0.0
vc-git-mode-line-string  1           0.0           0.0
2 голосов
/ 17 июля 2011

Вы можете отключить vc-режим , установив vc-handled-backends в nil в вашем .emacs.

...