Okazuje się, że bardzo zróżnicowana wydajność była związana z odśmiecaniem. Każde wywołanie funkcji będzie działało wolniej, dopóki nie zostanie uruchomione czyszczenie pamięci. Z zapasowymi emacsami, gc był uruchamiany co kilka sekund, ale miałem init w linii, aby skrócić czas uruchamiania, który ustawił próg gc-cons na 20 MB, a to oznaczało, że gc był uruchamiany znacznie rzadziej, powodując zgłaszaj coraz wolniejsze taktowanie, aż gc zostanie uruchomiony po kilku minutach, wtedy czasy zaczną spadać i znów będą szybkie.
Po przywróceniu domyślnej wartości gc-cons-threshhold testowanie stało się łatwiejsze.
Następnie profilowałem pod kątem pamięci za pomocą wbudowanego profilera ( M-x profiler-start
) i odkryłem, że wywołania do składni-ppss powodowały najwięcej alokacji, więc po pewnej optymalizacji w celu wywołania składni-pps rzadziej osiągałem akceptowalną wydajność.
Korzystanie z trybu blokowania czcionek (dodawanie funkcji przez rejestr blokady blokad) wydaje się być najłatwiejszym sposobem na niezawodne blokowanie czcionek wielowierszowych, dlatego wybrałem tę metodę.
Edycja: Po odkryciu, że wydajność wciąż nie była wystarczająca w bardzo dużych buforach, spędziłem dużo czasu optymalizując użycie procesora i alokację procesora, mierząc poprawę wydajności za pomocą wbudowanego narzędzia Emacs profiler ( M-x profiler-start
). Jednak Emacs nadal się jąka i zawiesza podczas szybkiego przewijania bardzo dużych buforów. Usunięcie funkcji blokady jit, w której się zarejestrowałem, jit-lock-register
spowoduje usunięcie jąkania i zawieszenie się, ale profilowanie pokazało, że funkcja blokady jit zakończyła się po około 8 ms, co powinno być wystarczająco szybkie, aby płynnie przewijać. Usunięcie połączenia z, jit-lock-register
a zamiast tego za pomocą zwykłego dopasowywania czcionek blokujących słowa kluczowe rozwiązało problem.
TLDR: Robienie tego było powolne i zacinało się:
(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")
(jit-lock-register 'my-font-lock-function)
Zrobienie tego było szybkie i nie zacinało się:
(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))))