You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Improve performance of [lsp-mode](https://github.com/emacs-lsp/lsp-mode) or [eglot](https://github.com/joaotavora/eglot) using a wrapper executable.
6
+
Improve the performance of [lsp-mode](https://github.com/emacs-lsp/lsp-mode) or [eglot](https://github.com/joaotavora/eglot) using a wrapper executable.
7
7
8
8
## Background & Prior work
9
9
10
10
(Huge thanks to @yyoncho for both maintaining lsp-mode and giving me the inspiration of this project).
11
11
12
12
According to [yyoncho](https://www.reddit.com/r/emacs/comments/ymrkyn/comment/iv90q4i/?utm_source=share&utm_medium=web2x&context=3),
13
-
the are several performance issues related to lsp-mode (mostly the same for elot):
13
+
the are several performance issues related to lsp-mode (mostly the same for eglot):
14
14
15
15
1. Json parsing in Emacs is slow
16
16
2. The server may block on sending data to emacs when the buffer is full, because Emacs may consume the data too slo
17
17
3. Similarly, Emacs may block on sending data to the server (hence block Emacs UI) when the buffer is full, because the server may be busy
18
18
19
19
@yyoncho tried to solve these issues by implementing [native async non-blocking jsonrpc](https://github.com/emacs-lsp/emacs).
20
-
The result is very good regarding performance. However it requires modifications in Emacs source code and it seems unlikely that those changes would be merged into upstream.
20
+
The result is very good regarding performance. However, it requires modifications in the Emacs source code and it seems unlikely that those changes would be merged into upstream.
21
21
Also, frankly I doubt that this would be well-maintained in the future since it also requires seperated code path in lsp-mode (I myself encountered some [issues](https://github.com/emacs-lsp/emacs/issues/12)).
22
22
23
23
24
-
## How this project work
24
+
## How this project works
25
25
26
-
This project provides an wrapperexecutable around lsp servers to work around above-mentioned issues:
26
+
This project provides a wrapper-executable around lsp server programs, to work around the above-mentioned issues:
27
27
28
-
- It converts json responses from server into **elisp bytecode** (in text representation) for Emacs to read.
28
+
- It converts json responses from the server into **elisp bytecode** (in text representation) for Emacs to read.
29
29
* e.g. `{"objs":[{"a":1},{"a":2}]}` would be converted to `#[0 "\301\302\300\303D\300\304D\"D\207" [:a :objs vector 1 2] 13]`
30
-
* This would improve the message parsing performance in Emacs by ~4x for large json objects, see benchmark result [here](https://github.com/blahgeek/emacs-lsp-booster/actions/runs/7416840025/job/20182439682#step:5:142)
31
-
* Although Emacs still needs to parse the text representation and interpret it into elisp object, the performance gain mainly comes from:
30
+
* This improves the message parsing performance in Emacs by ~4x for large json objects, see benchmark result [here](https://github.com/blahgeek/emacs-lsp-booster/actions/runs/7416840025/job/20182439682#step:5:142)
31
+
* Although Emacs still needs to parse the text representation and interpret it into elisp objects, the performance gain mainly comes from the following:
32
32
* Parsing (`read`ing) elisp object is apparently better optimized and simpler in Emacs
33
33
* Using bytecode to construct objects, we can eliminate duplicated objects (e.g. the "a" json key in above example)
34
-
- It separates reading and writing into different threads and keeps pending messages in internal buffers, to avoid blocking on IO, which solves above-mentioned issue (2) and (3).
34
+
- It separates reading and writing into different threads and keeps pending messages in internal buffers, to avoid blocking on IO, which solves the above-mentioned issues (2) and (3).
35
35
36
36
Overall, this achieves similar result as the native async non-blocking jsonrpc approach without requiring modifications in Emacs source code.
37
37
@@ -42,9 +42,9 @@ Generally, what you need to do is:
42
42
43
43
1. Wrap your lsp server command with this `emacs-lsp-booster` executable.
44
44
For example, if the original lsp server command is `pyright-langserver --stdio`, configure lsp-mode or eglot to run `emacs-lsp-booster pyright-langserver --stdio` instead.
45
-
2. Advise the json parsing function in lsp-mode or eglot to try to parse the input as bytecode instead of json.
45
+
2. Advise/update the json parsing function in lsp-mode or eglot to try to parse the input as bytecode prior to parsing it as json.
46
46
47
-
See more detailed steps below.
47
+
See more detailed configuration steps below.
48
48
49
49
### Obtain or build `emacs-lsp-booster`
50
50
@@ -101,12 +101,12 @@ Done! Now try to use lsp-mode as usual.
101
101
102
102
### Configure `eglot`
103
103
104
-
Please see https://github.com/blahgeek/emacs-lsp-booster/issues/1 . Huge thanks to @jdtsmith
104
+
Please see https://github.com/blahgeek/emacs-lsp-booster/issues/1for information on configuring `eglot`. Huge thanks to @jdtsmith
105
105
106
106
### How to verify it's working
107
107
108
108
1. Check that `emacs-lsp-booster` process is running
109
-
2. Check the stderr buffer (e.g. for lsp-mode, `*pyright::stderr*` buffer), it should contain `emacs_lsp_booster` related log.
109
+
2. Check the stderr buffer (e.g. for lsp-mode, `*pyright::stderr*` buffer; for eglot, the ` EGLOT (...) stderr*` buffer, note the leading space); it should contain `emacs_lsp_booster` related log.
0 commit comments