Çılgınca değişen performansın çöp toplama ile ilgili olduğu ortaya çıktı. Bir çöp toplama çalıştırılana kadar işleve yapılan her çağrı yavaşlar. Hisse senedi emacs ile gc, her birkaç saniyede bir çalıştırıldı, ancak gc-eksilerini eşik değerini 20 MB'ye ayarlayan başlatma süresini iyileştirmek için init.el'de bir satırım vardı ve bu, gc'nin daha seyrek çalıştırıldığı anlamına geliyor ve kıyaslamaların Bir gc birkaç dakika sonra çalıştırılıncaya kadar daha yavaş ve yavaş zamanlama rapor edin, sonra zaman düşecek ve tekrar hızlı olacaktır.
Varsayılan gc-cons-threshhold'a geri döndükten sonra, kıyaslama daha kolay hale geldi.
Sonra yerleşik profiler ( M-x profiler-start
) ile bellek için profilli ve sözdizimi-ppss çağrıları en çok tahsis neden olduğunu keşfetti, bu yüzden sözdizimi-ppss daha az sıklıkta aramak için bazı optimizasyon sonra kabul edilebilir performans elde etti.
Jit-lock-mode (jit-lock-register ile bir işlev eklemek) kullanmak, çok satırlı yazı tipi kilidinin güvenilir bir şekilde çalışmasını sağlamanın en kolay yolu gibi görünüyor, bu yüzden seçtiğim yöntem buydu.
Düzenleme: Performansın hala çok büyük arabelleklerde yeterince iyi olmadığını keşfettikten sonra, dahili Emacs profiler ( M-x profiler-start
) ile performans iyileştirmelerini ölçerek, cpu kullanımı ve tahsisini optimize etmek için çok zaman harcadım . Bununla birlikte, Emacs çok büyük arabelleklerde hızlı bir şekilde kaydırılırken hala kekeliyor ve asılı kalıyordu. Kaydettiğim jit kilit işlevinin jit-lock-register
kaldırılması kekemeliği ve askıda kalmayı ortadan kaldırır, ancak profilleme jit kilit işlevinin yaklaşık 8 ms'de tamamlandığını gösterdi ve bu da düzgün kaydırma için yeterince hızlı olmalıdır. Çağrıyı kaldırmak jit-lock-register
ve bunun yerine normal bir font-lock-keywords eşleştiricisi kullanmak sorunu çözdü.
TLDR: Bunu yapmak yavaştı ve kekeliyordu:
(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")
(jit-lock-register 'my-font-lock-function)
Bunu yapmak hızlıydı ve kekelemedi:
(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")
(defun my-font-lock-matcher (limit)
(my-font-lock-function (point) limit)
nil)
(setq font-lock-defaults
(list
...
;; Note that the face specified here doesn't matter since
;; my-font-lock-matcher always returns nil and sets the face on
;; its own.
`(my-font-lock-matcher (1 font-lock-keyword-face nil))))