Magit sangat lambat di Windows. Bagaimana cara saya mengoptimalkan?

15

Saya terpaksa menggunakan Windows 10 untuk proyek. Ya, saya lebih suka menggunakan GNU / Linux. Untuk menjaga kewarasan saya, saya sudah mencoba menganggap Windows sebagai bootloader untuk Emacs :)

Sayangnya, Magit (salah satu bagian favorit saya dari Emacs, yang juga menebus kurangnya baris perintah yang baik pada Windows) lambat sekali. Saya memiliki SSD, 16 GB RAM dan quad-core i7 tetapi butuh delapan detik untuk mengeksekusi magit-statuspada repositori kecil. Lalu, ketika saya ingin melakukan perubahan lain, dibutuhkan sekitar 5 detik per file .

Inilah yang saya coba:

  • $ git config --global core.preloadindex true
  • $ git config --global core.fscache true
  • $ git config --global gc.auto 256
  • Menambahkan seluruh proyek ke daftar pengecualian Windows Defender (AV saya saja)
  • Mengatur magit-git-executableke msysgit biasa yang saya unduh ( https://git-for-windows.github.io/ ). Saya memeriksa dan ini git statusmembutuhkan waktu <1 detik. Saya tahu itu magit-statuslebih banyak, tetapi ini terlalu banyak.

Adakah yang bisa menyarankan cara untuk membuat ini lebih cepat? Saya tidak bisa membayangkan orang menggunakan Magit di Windows seperti ini.

Disarankan bahwa pertanyaan ini adalah duplikat, tetapi mereka bertanya:

Saya berjuang untuk memahami mengapa Emacs memiliki waktu startup yang lebih singkat di Ubuntu daripada Windows. Adakah yang tahu jawabannya?

Saya tahu setidaknya beberapa alasan mengapa Emacs, Git, dan Magit lebih lambat di Windows. Saya bertanya bagaimana cara mengoptimalkan Magit untuk melakukan lebih sedikit, atau hasil cache, atau sesuatu, bahkan jika itu dengan mengorbankan fungsionalitas.

Hut8
sumber
git-statusDibutuhkan <1 detik? Ini harus pada dasarnya instan. Apakah ada penundaan yang jelas sama sekali?
PythonNut
Apakah Anda memiliki masalah yang sama menjalankan gitperintah yang setara dari baris perintah?
elethan
Saya pikir pilihan default magit magit-git-executablemungkin akan sedikit lebih cepat (yang ada di dalam cmddan binsebenarnya adalah pembungkus, jika executable-findmengembalikan salah satunya magit akan mencoba untuk mengatur magit-git-executableke git "nyata"). 8 detik untuk repositori kecil terdengar seperti ada sesuatu yang salah, butuh ~ 0.8s untuk repo magit di sini (Windows 8).
npostavs
1
Juga, untuk waktu yang lebih akurat, Anda dapat mengatur magit-refresh-verboseke t.
pengasuh

Jawaban:

11

Saya sebenarnya telah melakukan banyak penelitian tentang ini dan pada dasarnya masalahnya adalah bahwa git untuk windows sucks

Ini adalah bug hulu: https://github.com/git-for-windows/git/issues/596 dan itu mengharuskan seseorang untuk menulis ulang skrip shell di C sehingga tidak ada lagi perintah forking. Bagi saya, ini adalah rebase interaktif yang merupakan pembunuh nyata (saya dapat memulai rebase interaktif, pergi membuat teh, kembali, membaca beberapa berita, minum teh, dan kemudian mungkin sudah selesai. Ini jauh lebih buruk daripada banyak orang pikir itu), tetapi panggilan umum seperti status juga cukup untuk mengganggu langkah kerja.

Alternatif lain adalah memperbarui jGit untuk mendukung perintah yang digunakan magit, dan kemudian menjalankannya di nailgun untuk mengurangi waktu startup JVM, saya memulai utas untuk membahas ini: http://dev.eclipse.org/mhonarc/lists/ jgit-dev / msg03064.html

Anda mungkin ingin membaca /programming/4485059 untuk beberapa speedup potensial, tetapi jujur ​​Anda hampir tidak akan melihatnya.

Sesuatu yang dapat Anda lakukan di magit adalah mengikuti saran penulis dalam menyiapkan minimal magit-statushanya untuk pementasan

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

jadi, apakah Anda tahu pengembang C atau Java berpengalaman yang dapat membantu dengan salah satu solusi untuk memperbaiki git atau jGit?

fommil
sumber
Saya tidak begitu yakin masalahnya adalah skrip shell vs. C, karena magit-statusmembutuhkan waktu yang sangat lama juga, dan saya tidak berpikir status menggunakan banyak skrip shell.
Pengasuh
1
Dan terima kasih untuk magit-statuskode "minimal" itu, sepertinya sedikit membantu saya (ini mengurangi magit-refreshwaktu saya menjadi 2-3 detik).
Pengasuh
Inilah yang saya inginkan. Terima kasih!
Hut8
1
ya, magit-stagingbutuh beberapa detik untuk saya juga. Cukup untuk mengganggu pikiranku, tetapi tidak cukup untuk menghancurkan hariku.
Dari
2
alasan mengapa magit-statuslambat adalah karena memanggil gitmungkin 10 atau 20 kali. Memulai proses baru pada Windows sangat lambat dibandingkan dengan platform GNU. Script shell adalah kasus ekstrim dari ini (karena hampir setiap pernyataan adalah proses baru)
fommil
2

Baru-baru ini melihat daftar call-processpanggilan dari magit-statusuntuk alasan lain, saya sadar bahwa beberapa dari mereka dapat di-cache. Dengan saran berikut magit-statustentang repo Magit berjalan dari 1,9 menjadi 1,3 detik (pengukuran saya sebelumnya 0,8 disebutkan dalam komentar adalah untuk komputer yang berbeda (lebih cepat)). Jika Anda sudah menggunakan magit-stagingjawaban lain, mungkin tidak akan banyak membantu: Saya melihat pengurangan dari 0,16 menjadi 0,12 detik (tapi itu hampir tidak lebih besar dari pengukuran noise).

PERINGATAN: Ini tidak perlu memperbarui cache, jadi ada masalah (terutama jika Anda mengutak-atik konfigurasi git Anda).

(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
sumber
mengapa Anda tidak menggunakan paket melpa.org/#/memoize ?
Dari
1
@fommil: Saya perlu mem-memo rev-parse per buffer untuk beberapa argumen. Saya tidak bisa melihat cara untuk melakukannya setelah melihat sepintas paket memoize. Juga dikatakan tidak bisa menangani memoizing nil.
npostavs