Magit extrem langsam in Windows. Wie optimiere ich?

14

Ich bin gezwungen, Windows 10 für ein Projekt zu verwenden. Ja, ich würde lieber GNU / Linux verwenden. Um meinen Verstand zu wahren, habe ich versucht, Windows als einen Bootloader für Emacs zu betrachten :)

Leider ist Magit (einer meiner Lieblingsteile von Emacs, der auch das Fehlen einer guten Befehlszeile unter Windows ausgleicht) unerträglich langsam. Ich habe eine SSD, 16 GB RAM und einen Quad-Core i7, aber die Ausführung auf einem kleinen Repository dauert acht Sekundenmagit-status . Wenn ich dann eine weitere Änderung vornehmen möchte, dauert es ungefähr 5 Sekunden pro Datei .

Folgendes habe ich versucht:

  • $ git config --global core.preloadindex true
  • $ git config --global core.fscache true
  • $ git config --global gc.auto 256
  • Hinzufügen des gesamten Projekts zur Windows Defender-Ausschlussliste (meine einzige AV-Liste)
  • Setzen Sie das magit-git-executableauf das reguläre msysgit, das ich heruntergeladen habe ( https://git-for-windows.github.io/ ). Ich habe nachgesehen und git statushier dauert <1 Sekunde. Ich weiß, dass magit-statusdas viel mehr ist, aber das ist zu viel.

Kann jemand Wege vorschlagen, um dies schneller zu machen? Ich kann mir nicht vorstellen, dass jemand Magit unter Windows so verwendet.

Es wurde vorgeschlagen, dass diese Frage ein Duplikat ist, aber sie fragten:

Ich habe Probleme zu verstehen, warum Emacs unter Ubuntu merklich kürzere Startzeiten haben als Windows. Kennt jemand die Antwort?

Ich kenne zumindest einige Gründe, warum Emacs, Git und Magit unter Windows langsamer sind. Ich frage, wie ich Magit optimieren kann , um weniger Dinge oder Cache-Ergebnisse oder ähnliches zu erledigen, auch wenn dies auf Kosten der Funktionalität geht.

Hut8
quelle
git-statusdauert <1 Sekunde? Es sollte im Wesentlichen augenblicklich sein. Gibt es überhaupt eine spürbare Verzögerung?
PythonNut
Haben Sie dieselben Probleme beim Ausführen der entsprechenden gitBefehle über die Befehlszeile?
Elethan
Ich denke, Magits Standardauswahl für magit-git-executablewird wahrscheinlich ein bisschen schneller sein (die in cmdund binsind tatsächlich Wrapper, wenn executable-findeiner von ihnen zurückkehrt, wird Magit versuchen magit-git-executable, den "echten" Git zu setzen). 8 Sekunden für ein kleines Repository klingt, als ob etwas anderes nicht in Ordnung wäre. Hier werden ~ 0,8 Sekunden für das Repository von Magit benötigt (Windows 8).
Npostavs
1
Auch für eine genauere Zeit, könnten Sie setzen magit-refresh-verboseauf t.
Kindermädchen

Antworten:

10

Ich habe tatsächlich ziemlich viel darüber recherchiert und grundsätzlich ist das Problem, dass git for windows nicht funktioniert

Dies ist der Upstream-Fehler: https://github.com/git-for-windows/git/issues/596 und es ist erforderlich, dass jemand Shell-Skripte in C neu schreibt, damit es keine Befehlsgabeln mehr gibt. Für mich ist es die interaktive Basis, die der wahre Killer ist (ich kann eine interaktive Basis eröffnen, Tee kochen, zurückkommen, einige Nachrichten lesen, den Tee trinken und dann ist es vielleicht zu Ende. Es ist viel schlimmer als viele Leute.) denke es ist), aber allgemeine statusähnliche Anrufe reichen auch aus, um den Arbeitsschritt zu unterbrechen.

Eine Alternative könnte sein, jGit zu aktualisieren, um die von magit verwendeten Befehle zu unterstützen, und es dann in nailgun auszuführen, um die Startzeit der JVM zu verringern. Ich habe einen Thread gestartet, um dies zu diskutieren: http://dev.eclipse.org/mhonarc/lists/ jgit-dev / msg03064.html

Vielleicht möchten Sie /programming/4485059 lesen, um Informationen zu möglichen Beschleunigungen zu erhalten, aber ehrlich gesagt werden Sie sie kaum bemerken.

Was Sie in magit tun können, ist, den Rat des Autors zu befolgen, um ein Minimum magit-statusnur für die Inszenierung zu erstellen

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

Kennen Sie erfahrene C- oder Java-Entwickler, die bei den Lösungen zur Behebung von git oder jGit helfen können?

fommil
quelle
Ich bin mir nicht sicher, ob das Problem Shell-Skripte im Vergleich zu C sind, da es auch magit-statussehr lange dauert und ich glaube nicht, dass der Status viele der Shell-Skripte verwendet.
Kindermädchen
1
Und danke für diesen "minimalen" magit-statusCode, der mir ein bisschen zu helfen scheint (er verkürzt meine magit-refreshZeit auf 2-3 Sekunden).
Kindermädchen
Genau das will ich. Vielen Dank!
Hut8
@Hut8 wie schnell ist magit mit dem minimalen code für dich inszeniert?
Kindermädchen
1
Der Grund, warum magit-statuses langsam ist, ist, dass es gitvielleicht 10 oder 20 Mal anruft . Das Starten neuer Prozesse unter Windows ist im Vergleich zu GNU-Plattformen extrem langsam. Die Shell-Skripte sind ein extremer Fall (weil so ziemlich jede Anweisung ein neuer Prozess ist)
14.
2

Nachdem ich mir kürzlich die Anrufliste call-processaus magit-statuseinem anderen Grund angesehen habe, ist mir aufgefallen, dass einige von ihnen zwischengespeichert werden können. Mit den folgenden Ratschlägen magit-statuszum Repo von Magit geht es von 1,9 auf 1,3 Sekunden (meine in den Kommentaren erwähnte vorherige Messung von 0,8 Sekunden war für einen anderen (schnelleren) Computer). Wenn Sie bereits magit-stagingvon der anderen Antwort Gebrauch machen , wird es wahrscheinlich nicht viel helfen: Ich habe eine Reduzierung von 0,16 auf 0,12 Sekunden gesehen (aber das ist kaum größer als das Messrauschen).

WARNUNG: Dies kümmert sich nicht um die Aktualisierung des Caches, daher können Probleme auftreten (insbesondere, wenn Sie an Ihrer Git-Konfiguration herumspielen).

(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
quelle
warum benutzt du nicht einfach das Paket melpa.org/#/memoize ?
15.
1
@fommil: Ich musste für einige Argumente Rev-Parse pro Puffer auswendig lernen . Nach einem kurzen Blick auf das memoize-Paket konnte ich keinen Weg finden, dies zu tun. Außerdem heißt es, dass es nicht mit dem Auswendiglernen umgehen kann nil.
Npostavs