rust-analyzer icon indicating copy to clipboard operation
rust-analyzer copied to clipboard

enabled a lens config CodeAction is very slow

Open A4-Tacks opened this issue 1 year ago • 8 comments

rust-analyzer version: rust-analyzer 1.82.0-nightly (7c2012d0 2024-07-26)

rustc version: rustc 1.82.0-nightly (7c2012d0e 2024-07-26)

editor or extension: Vim 9.1 coc-rust-analyzer

relevant settings:

{
    "rust-analyzer.updates.checkOnStartup": false,
    "rust-analyzer.lens.references.method.enable": true
}

code snippet to reproduce src/main.rs:

use std::{fmt::Display, ops::Deref};

#[derive(Debug, Clone, Eq)]
pub enum ParseLine<'a> {
    Label(&'a str),
    Args((), u32),
}
impl<'a> PartialEq for ParseLine<'a> {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::Label(l0), Self::Label(r0)) => l0 == r0,
            (Self::Args(l0, _), Self::Args(r0, _)) => l0 == r0,
            _ => false,
        }
    }
}
impl<'a> TryFrom<Vec<&'a str>> for ParseLine<'a> {
    type Error = ();

    fn try_from(_: Vec<&'a str>) -> Result<Self, Self::Error> {
        Ok(Self::Args((), 0))
    }
}
impl<'a> From<&'a str> for ParseLine<'a> {
    fn from(_: &'a str) -> Self {
        todo!()
    }
}
impl<'a> From<()> for ParseLine<'a> {
    fn from(_: ()) -> Self {
        todo!()
    }
}
impl<'a> Display for ParseLine<'a> {
    fn fmt(&self, _: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        todo!()
    }
}


fn main() { }

reproduce steps:

  1. open file src/main.rs, CPU Usage to 400%, Memory Usage to 851 MB
  2. in line 11 => l0 start CodeAction, is slow
  3. any edit and save file, and start CodeAction is very slow, Max CPU Usage to 700%, Memory Usage to 1350 MB

A4-Tacks avatar Aug 23 '24 23:08 A4-Tacks

I think there's a couple of different things here:

  • high CPU usage on load (especially if you have some dependencies in Cargo.toml) is probably the cache priming, which was added specifically for Vim users who open and close their editor all the time (as opposed to using :e); you can disable that
  • the memory usage seems fine, I get 650 MB in Code without cache priming
  • the references lens is very slow because it has to infer a lot of types, from all over the project, and it might be looking in places it shouldn't, which slows it down some more; we've recently merged some nice optimizations for reference search, though
  • I can't reproduce high CPU or memory usage when triggering the code actions at that location

lnicola avatar Aug 24 '24 06:08 lnicola

  • the references lens is very slow because it has to infer a lot of types, from all over the project, and it might be looking in places it shouldn't, which slows it down some more; we've recently merged some nice optimizations for reference search, though

I update to rust-analyzer 1.82.0-nightly (eff09483 2024-08-22) still very slow, test crate dependencies count is zero

Screenshot_20240824_153639

  • high CPU usage on load (especially if you have some dependencies in Cargo.toml) is probably the cache priming, which was added specifically for Vim users who open and close their editor all the time (as opposed to using :e); you can disable that

The main slow is to edit and save


use "rust-analyzer.lens.references.method.enable": false and optional enable other lens, is fast

A4-Tacks avatar Aug 24 '24 07:08 A4-Tacks

I update to rust-analyzer 1.82.0-nightly (eff09483 2024-08-22)

r-a changes only get into the rustup component once every week or so. The recent optimizations aren't there yet.

lnicola avatar Aug 24 '24 07:08 lnicola

  • the memory usage seems fine, I get 650 MB in Code without cache priming

Wait, Is it still the same when "rust-analyzer.lens.references.method.enable": false ? My memory usage is 405 MB

A4-Tacks avatar Aug 24 '24 07:08 A4-Tacks

Yeah, 396 MB without the lens, 650 MB with it enabled. The issues with the lens are that:

  • we do a text search for the method name (hopefully it's not called new, but https://github.com/rust-lang/rust-analyzer/pull/17927, which you don't have, added a fancy optimization), but then we have to infer all the types around the calls to make sure we got the right method, and this includes trait solving
  • I think we're also searching in the standard library code, and maybe even dependencies

lnicola avatar Aug 24 '24 08:08 lnicola

I don't understand why other lens.references don't cause very slow performance

enable all lens (exclude rust-analyzer.lens.references.method.enable) is also fast

A4-Tacks avatar Aug 24 '24 08:08 A4-Tacks

Because most of the others we can find without doing too much work. If you're looking at a ToString trait, you can search for the ToString text, make sure it's imported or qualified with the same path, and there you are, you either have a match or you didn't.

But if you're searching for new or eq, for each match we have to figure out where the method comes from (inherent or from a trait), and that's a lot more work.

Anyway, feel free to download a binary from https://github.com/rust-lang/rust-analyzer/releases/tag/2024-08-19 and see if it's any faster. Although:

This PR doesn't consider trait methods (they have a bunch of other problems), so no, this won't change.

lnicola avatar Aug 24 '24 08:08 lnicola

Anyway, feel free to download a binary from https://github.com/rust-lang/rust-analyzer/releases/tag/2024-08-19 and see if it's any faster. Although:

I downloaded rust-analyzer-aarch64-unknown-linux-gnu.gz and use, but the still slow

rust-analyzer 0.3.1756-standalone (e402c494b 2023-12-01) is also slow

A4-Tacks avatar Aug 24 '24 08:08 A4-Tacks

Have the same issue here

I did not notice it before updating to latest version v0.3.2180 maybe it wasn't there before? Or it didn't gave "empty space" when we implement something

NicolasWent avatar Nov 15 '24 19:11 NicolasWent