From 0cbf6a7a7683d81095b3291be33e4be7936110d2 Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Fri, 16 Aug 2024 10:02:36 +0300 Subject: [PATCH] Test for word boundary in `FindUsages` This speeds up short identifiers search significantly, while unlikely to have an effect on long identifiers (the analysis takes much longer than some character comparison). Tested by finding all references to `eq()` (from `PartialEq`) in the rust-analyzer repo. Total time went down from 100s to 10s (a 10x reduction!). --- .../rust-analyzer/crates/ide-db/src/search.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs index 9e01a6d44083c..d9af9f1871723 100644 --- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs +++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs @@ -503,6 +503,20 @@ impl<'a> FindUsages<'a> { if !search_range.contains_inclusive(offset) { return None; } + // If this is not a word boundary, that means this is only part of an identifier, + // so it can't be what we're looking for. + // This speeds up short identifiers significantly. + if text[..idx] + .chars() + .next_back() + .is_some_and(|ch| matches!(ch, 'A'..='Z' | 'a'..='z' | '_')) + || text[idx + finder.needle().len()..] + .chars() + .next() + .is_some_and(|ch| matches!(ch, 'A'..='Z' | 'a'..='z' | '_' | '0'..='9')) + { + return None; + } Some(offset) }) }