Stream: t-compiler/wg-rls-2.0

Topic: Completion latency?


Ivan Molodetskikh (Jan 06 2020 at 13:06, on Zulip):

Hello! I'm trying rust-analyzer again now that cargo-watch is built-in (finally! can't live without this one). It looks like the completion takes about 1.5 seconds to pop up after I input something., which is just long enough to be annoying. RLS is almost instant—after it's done building its database, that is. Is it supposed to take this long? I'm on neovim with LanguageClient-neovim.

matklad (Jan 06 2020 at 13:09, on Zulip):

1.5 seconds seems excessive! Our completion is not as speedy as I would like yet, but it should fit into hundreds of milliseconds. Does it happen every time or only for specific projects?

matklad (Jan 06 2020 at 13:10, on Zulip):

Peek-2020-01-06-14-09.gif

This is how completion works in rust-analyzer itself

Ivan Molodetskikh (Jan 06 2020 at 13:15, on Zulip):

Hmm, looks like it's generally fast, but on this small 1-file project using vulkano it takes around 1 second.

matklad (Jan 06 2020 at 13:16, on Zulip):

@Ivan Molodetskikh that's wonderful! Could you publish this 1-line project with Cargo.lock to github?

Ivan Molodetskikh (Jan 06 2020 at 13:20, on Zulip):

https://github.com/YaLTeR/rust-analyzer-long-completion

Ivan Molodetskikh (Jan 06 2020 at 13:21, on Zulip):

Both completing something from existing variables (e.g. pipeline) and just doing a let temp = "asd"; temp. has about 1 second of latency for me.

matklad (Jan 06 2020 at 13:26, on Zulip):

yup, reproduced!

Florian Diebold (Jan 06 2020 at 13:30, on Zulip):

it might be related to the "profiling rust-analyzer" topic (especially considering vulkano produces lots of items with macros, I think)

matklad (Jan 06 2020 at 13:38, on Zulip):

@Florian Diebold I think that's a different problem, here's profile: https://gist.github.com/matklad/7e4e0ffcd6c2e8965dcf5a2da61fb149 (I love our profiling infra).

The crate_def_map takes 0ms, which is expected: it is a const external crate.

OTOH, the infer query takes quite a while. Which... is expected, give Tomaka's code style :D, and which makes this an interesting test case

Florian Diebold (Jan 06 2020 at 13:41, on Zulip):

wow

Florian Diebold (Jan 06 2020 at 13:41, on Zulip):

I don't quite understand why infer would take so long though

Florian Diebold (Jan 06 2020 at 13:42, on Zulip):

it might lead to lots of trait queries, but I don't see any in the profile

matklad (Jan 06 2020 at 13:42, on Zulip):
                          380ms - trait_solve_query
                          219ms - trait_solve_query (213 calls)
Ivan Molodetskikh (Jan 06 2020 at 13:42, on Zulip):

Hahaha wow, that's a lot of traits! Maybe it's this thing killing it? https://docs.rs/vulkano/0.16.0/vulkano/pipeline/struct.GraphicsPipelineBuilder.html

Florian Diebold (Jan 06 2020 at 13:42, on Zulip):

ah wait, that's just infer and no do_infer in the end, so it's apparently again salsa revalidation taking so long?

matklad (Jan 06 2020 at 13:42, on Zulip):

They are kicked by diagnostics query (the infer in completion basically waits for those complete)

Florian Diebold (Jan 06 2020 at 13:42, on Zulip):

and probably again because of all the trait queries :confused:

matklad (Jan 06 2020 at 13:43, on Zulip):

I don't think this is re-validation. Rather, one thread blocks while the other computes the result

Florian Diebold (Jan 06 2020 at 13:44, on Zulip):

ah, that could be it

matklad (Jan 06 2020 at 13:45, on Zulip):

This can't be revalidation, b/c infer is a volatile query, and is just thrown away without revalidation.

However, I wonder if adding that caching to that_sovler query we talked about the other day might help here as well

Florian Diebold (Jan 06 2020 at 13:48, on Zulip):

This can't be revalidation, b/c infer is a volatile query, and is just thrown away without revalidation.

It is? I don't see that here https://github.com/rust-analyzer/rust-analyzer/blob/1953ac17fd8c93d2145ec3103fd39dd9d6c8fd30/crates/ra_hir_ty/src/db.rs#L26 (and I don't think that'd be a good idea, when we're calling it for every function in a file for diagnostics?)

matklad (Jan 06 2020 at 13:49, on Zulip):

the trait_solver_query is volatile, so, once we try validate first of trait_solve_query, we immediately thrown the result awway

matklad (Jan 06 2020 at 13:51, on Zulip):

Yeah, caching trait_solver gives a more reasonable 216ms - handle_completion

matklad (Jan 06 2020 at 13:51, on Zulip):

(of which 150ms seem to be revalidation)

matklad (Jan 06 2020 at 13:53, on Zulip):

(also, to give some scale, I think we should aim at 16ms for completion latency. Shouldn't be that hard: it's just text processing of low-megabytes of text after all :) )

matklad (Jan 06 2020 at 13:59, on Zulip):

@Florian Diebold submitted a PR with caching: https://github.com/rust-analyzer/rust-analyzer/pull/2752.

nikomatsakis (Jan 06 2020 at 15:42, on Zulip):

this reminds me that figuring out how to integrate trait solver caching with salsa is on my list of "open problems"

Ivan Molodetskikh (Jan 10 2020 at 13:59, on Zulip):

So, any issue I could subscribe to to track this?

matklad (Jan 10 2020 at 14:04, on Zulip):

@Ivan Molodetskikh I think this might be a good proxy for "chalk is slow": https://github.com/rust-lang/chalk/issues/298. There's no a dedicated issue for chalk caching yet

Ivan Molodetskikh (Jan 10 2020 at 14:22, on Zulip):

Alright, thanks

Last update: Jun 04 2020 at 18:25UTC