-
Notifications
You must be signed in to change notification settings - Fork 184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use orjson to de-/serialize json-rpc messages #2513
Conversation
It can be tested with this package that Rafal wrote |
According to this plugin, orjson doesn't make any difference. Tests results in 0.189 - 0.192 with both json and orjson on my machine. |
This thread has some information of where bottle necks are located, and how they were solved |
Yeah, and those include json serialization performance being an aspect. With promised performance of orjson I would have expected a little improvement with regards to deserialize messages from language servers. Maybe payload is just too small to outweight overhead for python->C/rust->python translations. |
That test tests performance of our |
I've added relevant tests in https://github.com/sublimelsp/LSP-performance-test It does appear to be twice as fast:
@deathaxe are you able to get this PR into a state that passes CI? |
For the record, that was parsing of a 50MB payload. Here are also results for parsing a tiny payload 10000 times:
Seems like orjson is still faster. |
Decide to use orjson or json on runtime, because 1. is something pyright linter can handle 2. works without touching unit tests
No idea how to satisfy pyright's limitations. I would prefer an import-time decision about using orjson or json. But pyright doesn't get that right. It doesn't even resolve orjson import. |
Add
|
Probably good enough as is. Getting the types right otherwise does indeed seem tricky. |
Just for comparison, the time for a single frame on a 120 Hz display is 8333.3 µs, so the performance improvement of parsing a 50 MB payload would make around 0.0012 % of a single frame time on a 120 Hz display. Not sure if that is worth to introduce another dependency... Also, such big payloads only seem to happen for completions, e.g. with LSP-typescript, where the server response for 36 MB already takes 2.9 seconds (see #2190). Then there is the time needed to create the CompletionItem objects and to pass them over the ST API, so we're probably at 3+ seconds. If the values from above are correct, we can now save 0.0000001 seconds from JSON parsing (for 50 MB). It doesn't look like to me that this would be the bottleneck... Edit: #2190 (comment) says current JSON parsing takes 0.293 seconds, so there is probably an error in your reported times? Should it be seconds instead of The Python code could be simplified to single lines: return orjson.loads(message) if orjson else json.loads(message.decode('utf-8')) |
That's just another flavor, but no real simplification. Actually such one-liners are often harder to read and don't execute faster by any means. |
The output of the test is actually in seconds. |
* origin/main: Use orjson to de-/serialize json-rpc messages (#2513)
* fix/remove-generators: Use orjson to de-/serialize json-rpc messages (#2513) remove unnecessary use of generators for session retrieval
After a recent discussion about json serialization performance, I was curious about impact orjson makes on LSP processing performance.
This PR showcases how orjson as transport de-/serializer.
During recent 2 weeks of daily use, I haven't realized any issues, but also my projects are small enough to not realize any significant impact on overall performance.
Maybe someone using heavy language servers such as typescript can try to benchmark it.