Magit은 Windows에서 매우 느립니다. 최적화는 어떻게합니까?


15

프로젝트에 Windows 10을 사용해야합니다. 예, 오히려 GNU / Linux를 사용하고 싶습니다. 제 정신을 유지하기 위해 Windows를 Emacs의 부트 로더로 간주하려고 노력했습니다. :)

불행히도, Magit (Windows에서 좋은 명령 줄이 부족한 Emacs에서 가장 좋아하는 부분 중 하나)은 견딜 수 없을 정도로 느립니다. SSD, 16GB 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을 사용하는 사람을 상상할 수 없습니다.

그것은 것을 제안했다 이 질문은 중복,하지만 그들은 질문 :

Emacs가 Windows보다 Ubuntu에서 시작 시간이 눈에 띄게 짧은 이유를 이해하기 위해 고심하고 있습니다. 누구나 답을 알고 있습니까?

Windows에서 Emacs, Git 및 Magit이 더 느린 이유를 적어도 알고 있습니다. 기능을 희생하더라도 더 적은 일을하거나 결과를 캐시하기 위해 Magit최적화하는 방법을 묻습니다 .


git-status<1 초 소요? 본질적으로 즉각적이어야합니다. 전혀 지각 가능한 지연이 있습니까?
PythonNut

git명령 행에서 동등한 명령을 실행하는 데 동일한 문제가 있습니까?
elethan

나는에 대한 magit의 기본 선택이 생각하는 magit-git-executable아마 조금 더 빠른 것 (에있는 사람 cmdbin경우에, 실제로 래퍼 executable-find반환 그들 중 하나 magit이 세트에 시도 할 것이다 magit-git-executable"진짜"자식에). 작은 저장소의 경우 8 초가 잘못되어 마치 magit의 저장소 (Windows 8)에서 ~ 0.8 초가 걸립니다.
npostavs


1
또한보다 정확한 시간을 위해로 설정할 magit-refresh-verboset있습니다.
nanny

답변:


11

나는 실제로 이것에 대해 많은 연구를 해 왔으며 근본적으로 문제는 Windows 용 자식이 짜증납니다.

이것은 업스트림 버그입니다 ( https://github.com/git-for-windows/git/issues/596). 그리고 더 이상 명령 분기가 없도록 누군가 C에서 셸 스크립트를 다시 작성해야합니다. 저에게있어, 진정한 살인자 인 인터랙티브 리베이스 (인터랙티브 리베이스를 시작하고, 차를 만들고, 돌아와 뉴스를 읽거나, 차를 마신 후 마쳤을 수도 있습니다.) 많은 사람들보다 훨씬 나쁩니다. 생각하십시오), 그러나 일반적인 상태와 같은 전화로도 업무 진행을 방해 할 수 있습니다.

대안은 magit이 사용하는 명령을 지원하도록 jGit을 업데이트 한 다음 nailgun에서 실행하여 JVM 시작 시간을 단축하는 것입니다. 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시간이 오래 걸리기 때문에 상태가 많은 쉘 스크립트를 사용한다고 생각하지 않습니다.
nanny

1
그리고 그 "최소한" magit-status코드에 감사합니다 . 조금 도움이 될 것 같습니다 (내 magit-refresh시간을 2-3 초로 줄입니다).
nanny

이것이 바로 내가 원하는 것입니다. 감사!
Hut8

1
p, magit-staging나도 몇 초 걸립니다. 내 생각을 방해하기에 충분하지만 내 하루를 파괴하기에는 충분하지 않습니다.
fommil

2
magit-status속도가 느린 이유 는 git10 회 또는 20 회 정도 호출되기 때문 입니다. Windows에서 새로운 프로세스를 시작하는 것은 GNU 플랫폼에 비해 매우 느립니다. 쉘 스크립트는 이것의 극단적 인 경우입니다 (거의 모든 문장이 새로운 프로세스이기 때문에)
fommil

2

최근 에 다른 이유로 call-process통화 목록을 살펴본 결과 magit-status일부는 캐시 될 수 있습니다. magit-statusMagit의 repo에 대한 다음 조언 으로 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.