MagitはWindowsで非常に遅くなります。最適化する方法


15

プロジェクトにWindows 10を使用せざるを得ません。はい、むしろGNU / Linuxを使用します。私の正気を保つために、私はWindowsをEmacsのブートローダーと見なそうとしました:)

残念ながら、Magit(Windowsでのコマンドラインの不足を補うEmacsの私のお気に入りの部分の1つ)は、耐えられないほど遅いです。SSD、16 GBのRAM、クアッドコアi7がありますが、小さなリポジトリで実行するには8秒かかり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がより多くの方法を行うことを知っているが、これは多すぎる。

誰もこれを速くする方法を提案できますか?このようにWindowsでMagitを使用している人は誰もいません。

この質問は重複していることが示唆されましたが、彼らは尋ねました:

UbuntuでのEmacsの起動時間がWindowsよりも著しく短い理由を理解するのに苦労しています。誰もが答えを知っていますか?

Emacs、Git、およびMagitがWindowsで遅い理由を少なくともいくつか知っています。Magitを最適化して、機能を犠牲にしている場合でも、より少ないことを実行したり、結果などをキャッシュしたりする方法を尋ねています。


git-status<1秒かかりますか?それは本質的に瞬時でなければなりません。目に見える遅延はありますか?
PythonNut

gitコマンドラインから同等のコマンドを実行しても同じ問題がありますか?
エレタン

私はのためのmagitのデフォルトの選択肢だと思うmagit-git-executableおそらく少し速くなります(中のものcmdbinすれば、実際のラッパーですexecutable-findリターンはそれらの1 magitがセットにしようとmagit-git-executable「本当」のgitに)。小さなリポジトリの8秒は、他の何かが間違っているように聞こえますが、ここではmagitのレポジトリに約0.8秒かかります(Windows 8)。
npostavs


1
また、より正確な時間のために、あなたが設定することができますmagit-refresh-verboset
ナニー

回答:


11

私は実際にこれについてかなり多くの研究を行ってきましたが、基本的に問題はWindows用のgitが吸うことです

これはアップストリームのバグです:https : //github.com/git-for-windows/git/issues/596。Cでシェルスクリプトを書き直してコマンドをフォークしないようにする必要があります。私にとって、それは本当の殺人者であるインタラクティブなリベースです(インタラクティブなリベースを開始し、お茶を作り、戻ってきて、ニュースを読んで、お茶を飲んで、それで終わったかもしれません。それは多くの人よりはるかに悪いです。と思われますが、一般的なステータスのような呼び出しでも作業ストライドを中断するのに十分です。

代替は、そのmagitが使用するコマンドをサポートするためにjGitを更新し、JVM起動時間を短縮するnailgunでそれを実行するかもしれないが、私はこれを議論するスレッドを開始しました:http://dev.eclipse.org/mhonarc/lists/ jgit-dev / msg03064.html

いくつかの潜在的な高速化について/programming/4485059を読みたいかもしれませんが、正直なところ、ほとんど気づかないでしょう。

magitでできることは、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))

だから、gitまたはjGitを修正するソリューションのいずれかを支援できる経験豊富なCまたはJava開発者を知っていますか?


問題がシェルスクリプトとCのmagit-statusどちらなのかはよくわかりませんが、これも非常に長い時間がかかるため、ステータスがシェルスクリプトの多くを使用しているとは思わないからです。
乳母

1
そして、その「最小限の」magit-statusコードに感謝します。それは少し助けになりそうです(私のmagit-refresh時間を2〜3秒に短縮します)。
乳母

これはまさに私が欲しいものです。ありがとう!
ハット8

1
うん、magit-staging私にも数秒かかります。私の思考を中断するのに十分ですが、私の一日を破壊するには十分ではありません。
-fommil

2
magit-status遅い理由は、git10回または20回呼び出されるからです。Windowsでの新しいプロセスの開始は、GNUプラットフォームに比べて非常に遅くなります。シェルスクリプトはこの極端なケースです(ほとんどすべてのステートメントは新しいプロセスであるため)
fommil

2

別の理由call-processからの呼び出しのリストを最近見たところ、magit-statusそれらのいくつかがキャッシュできることがわかりました。magit-statusMagitのレポに関する次のアドバイスでは、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-parseをメモする必要がありました。memoizeパッケージをざっと見ても、そうする方法がわかりませんでした。また、それはメモ化を処理できないと言いnilます。
npostavs
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.