Ternyata kinerja yang sangat bervariasi terkait dengan pengumpulan sampah. Setiap panggilan ke fungsi akan menjadi lebih lambat sampai pengumpulan sampah dijalankan. Dengan emacs saham, gc dijalankan setiap beberapa detik, tetapi saya memiliki garis di init.el saya untuk meningkatkan waktu startup yang menetapkan gc-cons-threshold menjadi 20 MB, dan itu berarti gc dijalankan lebih jarang, menyebabkan tolok ukur untuk laporkan lebih lambat dan waktu lebih lambat sampai gc dijalankan setelah beberapa menit, maka waktu akan menurun dan cepat lagi.
Setelah kembali ke ambang default gc-cons-threshold, pembandingan menjadi lebih mudah.
Saya kemudian membuat profil untuk memori dengan built in profiler ( M-x profiler-start
), dan menemukan bahwa panggilan ke sintaks-pps menyebabkan alokasi terbanyak, jadi setelah beberapa optimasi untuk memanggil sintaks-pps kurang sering saya mencapai kinerja yang dapat diterima.
Menggunakan mode jit-lock-mode (menambahkan fungsi melalui jit-lock-register) tampaknya menjadi cara termudah untuk mendapatkan penguncian font multi baris agar dapat bekerja dengan andal, jadi itulah metode yang saya pilih.
Sunting: Setelah menemukan bahwa kinerja masih tidak cukup baik di buffer yang sangat besar, saya menghabiskan banyak waktu untuk mengoptimalkan penggunaan dan alokasi cpu, mengukur peningkatan kinerja dengan built in Emacs profiler ( M-x profiler-start
). Namun, Emacs masih akan gagap dan menggantung ketika menggulir dengan cepat melalui buffer yang sangat besar. Menghapus fungsi jit-lock yang saya daftarkan jit-lock-register
akan menghilangkan kegagapan dan hang, tetapi profiling menunjukkan fungsi jit-lock selesai sekitar 8 ms yang seharusnya cukup cepat untuk pengguliran yang lancar. Menghapus panggilan ke jit-lock-register
dan sebagai gantinya menggunakan pencocokan font-lock-keywords biasa menyelesaikan masalah.
TLDR: Melakukan ini lambat dan akan gagap:
(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")
(jit-lock-register 'my-font-lock-function)
Melakukan ini dengan cepat dan tidak akan gagap:
(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))))