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
Copy file name to clipboardExpand all lines: README.md
+19-16
Original file line number
Diff line number
Diff line change
@@ -13,36 +13,37 @@ According to [yyoncho](https://www.reddit.com/r/emacs/comments/ymrkyn/comment/iv
13
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
-
2. The server may block on sending data to emacs when the buffer is full, because Emacs may consume the data too slo
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
-
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 the Emacs source code and it seems unlikely that those changes would be merged into upstream.
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)).
16
+
2. The server may block on sending data to emacs when the buffer is full, because Emacs is consuming the data too slowly
17
+
3. Similarly, Emacs may block while attempting to send data to the server (hence blocking the Emacs UI), because the server may be busy
22
18
19
+
@yyoncho tried to solve these issues by implementing a [native async non-blocking jsonrpc](https://github.com/emacs-lsp/emacs) fork of emacs.
20
+
The result is very good regarding performance. However, it requires modifications in the Emacs source code and it seems unlikely that those changes could be merged upstream.
21
+
Also, it could prove difficult to maintain, since it also requires a separate code path in lsp-mode (I myself encountered some [issues](https://github.com/emacs-lsp/emacs/issues/12)).
23
22
24
23
## How this project works
25
24
26
25
This project provides a wrapper-executable around lsp server programs, to work around the above-mentioned issues:
27
26
28
-
- It converts json responses from the server into **elisp bytecode** (in text representation) for Emacs to read.
27
+
- It converts json messages from the server at high speed directly into **elisp bytecode** (in text representation) for Emacs to read.
29
28
* 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 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)
29
+
* 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
30
* Although Emacs still needs to parse the text representation and interpret it into elisp objects, the performance gain mainly comes from the following:
32
31
* Parsing (`read`ing) elisp object is apparently better optimized and simpler in Emacs
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 the above-mentioned issues (2) and (3).
32
+
*By using bytecode to construct objects, we can eliminate duplicated objects (e.g. the "a" json key in above example)
33
+
- It separates reading and writing into different threads and keeps pending messages in internal buffers within each thread, to avoid blocking on IO. This solves issues (2) and (3) mentioned above.
35
34
36
-
Overall, this achieves similar result as the native async non-blocking jsonrpc approach without requiring modifications in Emacs source code.
35
+
Overall, this _lsp server wrapper_ strategy achieves similar result as the native async non-blocking jsonrpc approach without requiring modifications in Emacs source code.
37
36
37
+
> [!IMPORTANT]
38
+
> At present only local lsp server programs which communicate by standard input/output can be wrapped, not servers communicating over network ports (local or remote).
38
39
39
40
## How to use
40
41
41
42
Generally, what you need to do is:
42
43
43
44
1. Wrap your lsp server command with this `emacs-lsp-booster` executable.
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/update the json parsing function in lsp-mode or eglot to try to parse the input as bytecode prior to parsing it as json.
45
+
For example, if the original lsp server command is `pyright-langserver --stdio`, configure lsp-mode or eglot to run `emacs-lsp-booster [flags --] pyright-langserver --stdio` instead.
46
+
2. Advise or update the json parsing function in `lsp-mode` or `eglot` to parse any bytecode input seen, prior to parsing it as json.
46
47
47
48
See more detailed configuration steps below.
48
49
@@ -51,7 +52,7 @@ See more detailed configuration steps below.
51
52
For linux users, you may download the prebuilt binary from [release](https://github.com/blahgeek/emacs-lsp-booster/releases).
52
53
*(The macOS binary in the release page lacks proper code signing for now.)*
53
54
54
-
Or alternatively, you may build the target locally:
0 commit comments