Magit надзвичайно повільно в Windows. Як оптимізувати?


15

Я змушений використовувати Windows 10 для проекту. Так, я вважаю за краще використовувати GNU / Linux. Щоб зберегти розум, я намагався розглядати Windows як завантажувач Emacs :)

На жаль, Magit (одна з моїх улюблених частин Emacs, яка також компенсує відсутність хорошого командного рядка в Windows) нестерпно повільний. У мене є SSD, 16 ГБ оперативної пам'яті і чотирьохядерний процесор i7 , але це займає вісім секунд , щоб виконати magit-statusна невелике сховище. Потім, коли я хочу провести ще одну зміну, це займає близько 5 секунд на файл .

Ось що я спробував:

  • $ git config --global core.preloadindex true
  • $ git config --global core.fscache true
  • $ git config --global gc.auto 256
  • Додавання всього проекту до списку виключень Windows Defender (мій єдиний AV)
  • Встановлення magit-git-executableзвичайного msysgit, який я завантажив ( https://git-for-windows.github.io/ ). Я перевірив і git statusтут потрібно <1 секунда. Я знаю, що magit-statusце робить набагато більше, але це занадто багато.

Хтось може запропонувати способи зробити це швидше? Я не уявляю, як хтось використовує Magit у Windows.

Було запропоновано, що це питання є дублікатом, але вони запитали:

Я намагаюся зрозуміти, чому Emacs помітно коротший час запуску Ubuntu, ніж Windows. Хтось знає відповідь?

Я знаю принаймні деякі причини, чому Emacs, Git і Magit повільніші в Windows. Я запитую, як я оптимізую Magit, щоб робити менше речей, або кешувати результати, або щось таке, навіть якщо це за рахунок функціональності.


git-statusзаймає <1 секунду? Це має бути по суті миттєвим. Чи є взагалі помітна затримка?
PythonNut

У вас є ті ж проблеми, які виконують еквівалентні gitкоманди з командного рядка?
елефан

Я думаю, що вибір за замовчуванням magit для magit-git-executable, ймовірно, буде трохи швидшим (ті, що є, cmdі binнасправді є обгортками, якщо executable-findповерне один з них magit спробує встановити magit-git-executableна "справжній" git). 8 секунд для невеликого сховища здається, що щось інше не так, хоча для магнітного репо тут тут ~ 0,8 секунди (Windows 8).
npostavs


1
Крім того , для більш точного часу, ви можете встановити magit-refresh-verboseв t.
няня

Відповіді:


11

Я фактично провів досить багато досліджень з цього питання, і в основному проблема полягає в тому, що git для Windows смокче

Це помилка вгорі: https://github.com/git-for-windows/git/isissue/596, і вона вимагає, щоб хтось переписав сценарії оболонки в C, щоб більше не було розгортання команд. Для мене, його інтерактивна база даних є справжнім вбивцею (я можу розпочати інтерактивну базу даних, піти робити чай, повернутися, почитати новини, випити чаю, а потім, можливо, це закінчено. Це набагато гірше, ніж багато людей думаю, що це так), але загальних статусних дзвінків також достатньо, щоб перервати робочий крок.

Альтернативою може бути оновлення jGit для підтримки команд, які використовує magit, а потім запуск його в цвяховому пістолеті для скорочення часу запуску JVM, я створив нитку для обговорення цього питання: http://dev.eclipse.org/mhonarc/lists/ jgit-dev / msg03064.html

Можливо, ви хочете прочитати /programming/4485059 для деяких потенційних прискорень, але, чесно, ви ледве помітите їх.

Щось ви можете зробити в магіті, це дотримуватися порад автора щодо створення мінімальних magit-statusдля постановки

;; WORKAROUND https://github.com/magit/magit/issues/2395
(define-derived-mode magit-staging-mode magit-status-mode "Magit staging"
  "Mode for showing staged and unstaged changes."
  :group 'magit-status)
(defun magit-staging-refresh-buffer ()
  (magit-insert-section (status)
    (magit-insert-untracked-files)
    (magit-insert-unstaged-changes)
    (magit-insert-staged-changes)))
(defun magit-staging ()
  (interactive)
  (magit-mode-setup #'magit-staging-mode))

Отже, чи знаєте ви досвідчених розробників C або Java, які могли б допомогти з будь-яким із рішень для виправлення git чи jGit?


Я не настільки впевнений, що проблема в скриптах оболонки проти C, тому що це також magit-statusзаймає дуже багато часу, і я не думаю, що статус використовує багато скриптів оболонок.
няня

1
І дякую за той "мінімальний" magit-statusкод, він, здається, трохи допомагає (скорочує мій magit-refreshчас на 2-3 секунди).
няня

Це саме те, що я хочу. Спасибі!
Хата8

1
Так, magit-stagingдля мене також потрібна пара секунд. Досить, щоб перервати моє мислення, але недостатньо, щоб зруйнувати мій день.
fommil

2
Причина, чому magit-statusповільно, полягає в тому, що вона дзвонить, gitможливо, в 10 або 20 разів. Запуск нових процесів у Windows надзвичайно повільний порівняно з платформами GNU. Сценарії оболонки - крайній випадок цього (адже майже кожен вислів - це новий процес)
fommil

2

Нещодавно переглянувши список call-processдзвінків з magit-statusіншої причини, у мене з'явилося, що деякі з них можна кешувати. З наступною порадою magit-statusщодо репортажу Magit йде від 1,9 до 1,3 секунди (моє попереднє вимірювання 0,8 секунди, згадане в коментарях, було для іншого (швидшого) комп'ютера). Якщо ви вже використовуєте magit-stagingіншу відповідь, це, ймовірно, не допоможе багато: я помітив скорочення з 0,16 до 0,12 секунди (але це ледь більше, ніж шум вимірювання).

ПОПЕРЕДЖЕННЯ. Це не стосується оновлення кешу, тому все може піти не так (особливо якщо ви співпадаєте зі своєю конфігурацією git).

(defvar-local magit-git--git-dir-cache nil)
(defvar-local magit-git--toplevel-cache nil)
(defvar-local magit-git--cdup-cache nil)

(defun memoize-rev-parse (fun &rest args)
  (pcase (car args)
    ("--git-dir"
     (unless magit-git--git-dir-cache
       (setq magit-git--git-dir-cache (apply fun args)))
     magit-git--git-dir-cache)
    ("--show-toplevel"
     (unless magit-git--toplevel-cache
       (setq magit-git--toplevel-cache (apply fun args)))
     magit-git--toplevel-cache)
    ("--show-cdup"
     (let ((cdup (assoc default-directory magit-git--cdup-cache)))
       (unless cdup
         (setq cdup (cons default-directory (apply fun args)))
         (push cdup magit-git--cdup-cache))
       (cdr cdup)))
    (_ (apply fun args))))

(advice-add 'magit-rev-parse-safe :around #'memoize-rev-parse)

(defvar-local magit-git--config-cache (make-hash-table :test 'equal))

(defun memoize-git-config (fun &rest keys)
  (let ((val (gethash keys magit-git--config-cache :nil)))
    (when (eq val :nil)
      (setq val (puthash keys (apply fun keys) magit-git--config-cache)))
    val))

(advice-add 'magit-get :around #'memoize-git-config)
(advice-add 'magit-get-boolean :around #'memoize-git-config)

чому ви просто не використовуєте пакунок melpa.org/#/memoize ?
fommil

1
@fommil: Мені потрібно було запам'ятати rev-синтаксичний аналіз на буфер для деяких аргументів. Я не міг побачити спосіб це зробити після короткого погляду на пам'ятний пакет. Крім того, він говорить, що не може впоратися із запам'ятовуванням nil.
npostavs
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.