Open Veykril opened 1 year ago
cc @roife , I think you were looking into speeding this up? or was that something else
I have tried placing the LineEndings
(normalize
) calculation within vfs-notify
(which runs in a separate thread), but I encountered two problems:
vfs::Change
, which would make the code more complex.sync_mut
, so calculation of LineEndings still needs to be done synchronously in these events, not in apply_document_changes
, but moved earlier to handle_did_open_text_document
and handle_did_change_text_document
. Therefore, it seems ineffective for scenarios involving frequent edits.I have considered using SIMD to accelerate the search process for \r
in normalize
(similar to what was done in LineIndex
). Perhaps this could be effective?
I have considered using SIMD to accelerate the search process for \r in normalize (similar to what was done in LineIndex). Perhaps this could be effective?
We can probably use the memchr
crate, it's already well-optimized.
We can probably use the
memchr
crate
I just tried using memchr
to calculate LineEndings
on a large file (composed of several files from rust-analyzer itself).
original
: 107.583msmemchr
: 13.981625msIt is worth noting that I use a brute-force algorithm in memchr
, so it can be further optimized for increased speed through careful refinement.
That looks very promising, optimizing seems enough to me. Offloading that to another thread is too complicated (and likely does not yield much in terms of benefits)
Is that on ARM? Because I don't see a NEON implementation in memchr
.
Is that on ARM? Because I don't see a NEON implementation in
memchr
.
Yes, I'm working on Apple Silicon.
I don't see a NEON implementation in
memchr
.
It added support for neon just months ago🙈: https://github.com/BurntSushi/memchr/pull/129
TIL #[cfg]
-gated files don't show up in the sidebar on https://docs.rs/memchr/latest/src/memchr/lib.rs.html#1-221 :sweat_smile:.
We handle client to server notifications synchronously, which means we should make sure that these notifications are processed fast as otherwise the server will block on them. If a user opens a very large rust file (100k+ lines) they will start encountering overly long loop and the general editor experience becomes very laggy. We can't make the processing for this notification async unfortunately so we should try and optimize the things we do there instead.
Relevant code snippets:
https://github.com/rust-lang/rust-analyzer/blob/bbcb77ea6fc08df598b20267afd6a44018b21f5b/crates/rust-analyzer/src/main_loop.rs#L746-L768 https://github.com/rust-lang/rust-analyzer/blob/bbcb77ea6fc08df598b20267afd6a44018b21f5b/crates/rust-analyzer/src/lsp_utils.rs#L135-L183 https://github.com/rust-lang/rust-analyzer/blob/bbcb77ea6fc08df598b20267afd6a44018b21f5b/crates/ide-db/src/line_index.rs#L57-L94
The main part here is the
LineIndex
calculation as we have to traverse the entire document text character by character, so we should look into possibly optimizing the creation of it.