I'm experiencing serious performance degradation whenever I'm in dart-mode
and LSP is enabled. This is a strange one because Emacs I don't experience any performance degradation on a fresh instance but within half-hour or so of editing Dart source files, the utilization of one of the CPU cores goes up to about 100% whenever the active mode's major mode is dart-mode
and LSP is enabled.
Had to resort to asking the community for help because I ran Emacs' profiler (profiler-start
-> stop -> report) multiple times and I always get the following unhelpful results:
1434 48% - timer-event-handler
1213 41% - timer-activate
1181 40% - timer--activate
309 10% timer--time-less-p
106 3% timer-inc-time
15 0% - apply
15 0% - auto-revert-buffers
8 0% auto-revert--buffer-candidates
1193 40% - redisplay_internal (C function)
858 29% - eval
536 18% mapconcat
178 6% - if
4 0% display-graphic-p
34 1% lsp--progress-status
20 0% - dap-mode-line
20 0% - dap--cur-session
4 0% lsp-workspace-get-metadata
12 0% - unless
4 0% if
4 0% mode-line-eol-desc
55 1% - #<compiled -0x13416d349593be12>
55 1% - apply
47 1% - redisplay--pre-redisplay-functions
31 1% - run-hook-with-args
31 1% - redisplay--update-region-highlight
23 0% - #<compiled 0x7c2ddd508885108>
23 0% - apply
12 0% - rectangle--unhighlight-for-redisplay
4 0% #<compiled 0x1aa0daf71b430848>
52 1% - mode-line-default-help-echo
40 1% - window-at-side-p
32 1% window-pixel-edges
305 10% - ...
305 10% Automatic GC
4 0% - command-execute
4 0% - funcall-interactively
4 0% - eval-last-sexp
4 0% elisp--eval-last-sexp
As you can see above, a large chunk of the execution is spent inside timer-related calls but it's not possible to identify the functions that are triggering the timers. Some time is also spent in internal Emacs functions responsible for rendering but it's not clear what's causing the redisplays. My question for the community is how can I dig deeper and improve the backtraces above? More specifically:
- How do I identify the functions that are repeatedly triggering the timers, ideally that doesn't involve altering/redefining the timer functions?
- How do I identify the causes for the redisplays?
(lsp-doctor)
gives:
Checking for Native JSON support: OK
Check emacs supports `read-process-output-max': OK
Check `read-process-output-max' default has been changed from 4k: OK
Byte compiled against Native JSON (recompile lsp-mode if failing when Native JSON available): OK
`gc-cons-threshold' increased?: OK
Using `plist' for deserialized objects? (refer to https://emacs-lsp.github.io/lsp-mode/page/performance/#use-plists-for-deserialization): OPTIONAL
Using emacs 28+ with native compilation?: OK
Running Emacs v29.0.50 (latest from master
as of now).