大幅に変化するパフォーマンスはガベージコレクションに関連していることがわかりました。関数の各呼び出しは、ガベージコレクションが実行されるまで遅くなります。ストックemacsでは、gcは数秒ごとに実行されていましたが、init-elにgc-cons-thresholdを20 MBに設定する起動時間を改善する行がありました。数分後にgcが実行されるまで、より遅いタイミングを報告すると、時間が急落し、再び速くなります。
デフォルトのgc-cons-threshholdに戻した後、ベンチマークが簡単になりました。
次に、組み込みのプロファイラー(M-x profiler-start
)を使用してメモリのプロファイルを作成し、syntax-ppssの呼び出しが最も多くの割り当てを引き起こすことを発見したため、syntax-ppssを呼び出すための最適化の後、許容できるパフォーマンスを達成しました。
jit-lock-modeを使用する(jit-lock-registerを介して関数を追加する)ことは、複数行フォントのロックを確実に機能させる最も簡単な方法のようです。
編集:非常に大きなバッファーでパフォーマンスがまだ十分でないことがわかった後、CPUの使用と割り当ての最適化に多くの時間を費やし、組み込みのEmacsプロファイラー(M-x profiler-start
)でパフォーマンスの改善を測定しました。しかし、非常に大きなバッファをすばやくスクロールすると、Emacsは依然として途切れてハングします。私が登録したjit-lock関数を削除すると、ing音jit-lock-register
とハングが削除されますが、プロファイリングにより、jit-lock関数が約8ミリ秒で完了することが示されました。呼び出しを削除しjit-lock-register
、代わりに通常のfont-lock-keywordsマッチャーを使用して、問題を解決しました。
TLDR:これを行うのは遅く、どもるでしょう:
(defun my-font-lock-function (start end)
"Set faces for font-lock between START and END.")
(jit-lock-register 'my-font-lock-function)
これを行うことは速くて、どもりません:
(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))))