Działa bardzo wolno w systemie Windows. Jak zoptymalizować?

15

Jestem zmuszony używać Windows 10 do projektu. Tak, wolę używać GNU / Linux. Aby zachować zdrowie psychiczne, starałem się traktować Windows jako program ładujący Emacsa :)

Niestety, Magit (jedna z moich ulubionych części Emacsa, która również rekompensuje brak dobrego wiersza poleceń w systemie Windows) jest nieznośnie powolny. Mam dysk SSD, 16 GB pamięci RAM i czterordzeniowy i7, ale wykonanie go w małym repozytorium zajmuje osiem sekundmagit-status . Następnie, gdy chcę wprowadzić kolejną zmianę, zajmuje to około 5 sekund na plik .

Oto, co próbowałem:

  • $ git config --global core.preloadindex true
  • $ git config --global core.fscache true
  • $ git config --global gc.auto 256
  • Dodanie całego projektu do listy wykluczeń Windows Defender (mój jedyny AV)
  • Ustawienie magit-git-executablezwykłego msysgit, który pobrałem ( https://git-for-windows.github.io/ ). Sprawdziłem i git statustutaj zajmuje <1 sekundę. Wiem, że magit-statusto znacznie więcej, ale to za dużo.

Czy ktoś może zasugerować, jak to zrobić szybciej? Nie mogę sobie wyobrazić nikogo używającego Magit w systemie Windows w ten sposób.

Zasugerowano, że to pytanie jest duplikatem, ale zadali:

Próbuję zrozumieć, dlaczego Emacs ma zauważalnie krótszy czas uruchamiania na Ubuntu niż Windows. Czy ktoś zna odpowiedź?

Znam przynajmniej kilka powodów, dla których Emacs, Git i Magit działają wolniej w systemie Windows. Pytam, w jaki sposób zoptymalizować Magit, aby wykonać mniej czynności, buforować wyniki lub coś podobnego, nawet jeśli odbywa się to kosztem funkcjonalności.

Chata 8
źródło
git-statuszajmuje <1 sekundę? Powinno to być zasadniczo natychmiastowe. Czy w ogóle jest jakieś zauważalne opóźnienie?
PythonNut
Czy masz takie same problemy z uruchamianiem równoważnych gitpoleceń z wiersza poleceń?
elethan
Myślę, że domyślny wybór magit magit-git-executablebędzie prawdopodobnie nieco szybszy (te wewnątrz cmdi binfaktycznie są opakowaniami, jeśli executable-findzwróci jeden z nich magit spróbuje ustawić magit-git-executablesię na „prawdziwego” gita). 8 sekund na małe repozytorium wydaje się, że coś innego jest nie tak, zajmuje ~ 0,8 s dla repozytorium magit tutaj (Windows 8).
npostavs 11.01.16
1
Ponadto, dla dokładniejszego czasu, możesz ustawić magit-refresh-verbosena t.
niania

Odpowiedzi:

11

Właściwie przeprowadziłem dość dużo badań na ten temat i zasadniczo problemem jest to, że git dla Windows jest do bani

To jest błąd nadrzędny: https://github.com/git-for-windows/git/issues/596 i wymaga to od kogoś przepisania skryptów powłoki w C, aby nie było więcej rozwidlania poleceń. Dla mnie to interaktywny rebase, który jest prawdziwym zabójcą (mogę uruchomić interaktywny rebase, zrobić herbatę, wrócić, poczytać jakieś wiadomości, wypić herbatę, a potem może to się skończy. Jest znacznie gorsze niż wiele osób myślę, że tak), ale ogólne wywołania przypominające status są wystarczające, aby przerwać pracę.

Alternatywą może być aktualizacja jGit do obsługi poleceń używanych przez magit, a następnie uruchomienie go w nailgun w celu skrócenia czasu uruchamiania JVM. Zacząłem wątek na ten temat: http://dev.eclipse.org/mhonarc/lists/ jgit-dev / msg03064.html

Możesz przeczytać /programming/4485059 dla niektórych potencjalnych przyspieszeń, ale szczerze mówiąc, prawie ich nie zauważysz.

W Magit można postępować zgodnie ze wskazówkami autora, aby ustawić minimalny magit-statusscenariusz

;; 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))

czy znasz jakichś doświadczonych programistów C lub Java, którzy byliby w stanie pomóc w rozwiązaniu jednego z problemów związanych z naprawą git lub jGit?

Fommil
źródło
Nie jestem pewien, czy problemem są skrypty powłoki vs. C, ponieważ magit-statuszajmuje to również naprawdę dużo czasu i nie sądzę, że status używa wielu skryptów powłoki.
niania
1
I dziękuję za ten „minimalny” magit-statuskod, wydaje mi się, że trochę mi pomaga (skraca mój magit-refreshczas do 2-3 sekund).
niania
Właśnie tego chcę. Dzięki!
Hut8
1
tak, magit-stagingzajmuje mi to również kilka sekund. Wystarczająco, by przerwać moje myślenie, ale nie wystarczy, by zniszczyć mój dzień.
fommil
2
Powodem, dla którego magit-statusjest powolny, jest to, że woła do git10 lub 20 razy. Uruchamianie nowych procesów w systemie Windows jest wyjątkowo wolne w porównaniu do platform GNU. Skrypty powłoki są tego ekstremalnym przypadkiem (ponieważ prawie każda instrukcja jest nowym procesem)
fommil
2

Po niedawnym przejrzeniu listy call-processpołączeń z magit-statusinnego powodu przyszło mi do głowy, że niektóre z nich można buforować. Z następującą radą magit-statusna temat repozytorium Magita wydłuża się z 1,9 do 1,3 sekundy (mój poprzedni pomiar 0,8 s wspomniany w komentarzach dotyczył innego (szybszego) komputera). Jeśli używasz już magit-stagingdrugiej odpowiedzi, prawdopodobnie nie pomoże to zbytnio: zauważyłem redukcję z 0,16 do 0,12 sekundy (ale to niewiele więcej niż szum pomiaru).

OSTRZEŻENIE: To nie zajmuje się aktualizacją pamięci podręcznej, więc może się nie udać (szczególnie jeśli masz problemy z konfiguracją 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)
npostavs
źródło
dlaczego po prostu nie użyjesz pakietu melpa.org/#/memoize ?
fommil
1
@fommil: Musiałem zapamiętać analizę obrotów na bufor dla niektórych argumentów. Nie mogłem znaleźć sposobu, aby to zrobić po pobieżnym spojrzeniu na pakiet zapamiętywania. Mówi także, że nie radzi sobie z zapamiętywaniem nil.
npostavs