diff --git a/Cargo.lock b/Cargo.lock index 1e53684735..57df633a4d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4243,6 +4243,7 @@ dependencies = [ "bitflags 2.9.2", "insta", "itertools 0.14.0", + "rayon", "regex", "ruff_db", "ruff_memory_usage", diff --git a/crates/ty_ide/Cargo.toml b/crates/ty_ide/Cargo.toml index 3b423ff1cb..bf6d0db791 100644 --- a/crates/ty_ide/Cargo.toml +++ b/crates/ty_ide/Cargo.toml @@ -23,6 +23,7 @@ ty_python_semantic = { workspace = true } ty_project = { workspace = true, features = ["testing"] } itertools = { workspace = true } +rayon = { workspace = true } regex = { workspace = true } rustc-hash = { workspace = true } salsa = { workspace = true, features = ["compact_str"] } diff --git a/crates/ty_ide/src/workspace_symbols.rs b/crates/ty_ide/src/workspace_symbols.rs index 96a65e92a1..738c208bcb 100644 --- a/crates/ty_ide/src/workspace_symbols.rs +++ b/crates/ty_ide/src/workspace_symbols.rs @@ -10,7 +10,6 @@ pub fn workspace_symbols(db: &dyn Db, query: &str) -> Vec { return Vec::new(); } - let mut results = Vec::new(); let project = db.project(); let options = SymbolsOptions { @@ -19,22 +18,34 @@ pub fn workspace_symbols(db: &dyn Db, query: &str) -> Vec { query_string: Some(query.into()), }; - // Get all files in the project let files = project.files(db); + let results = std::sync::Mutex::new(Vec::new()); + { + let db = db.dyn_clone(); + let files = &files; + let options = &options; + let results = &results; - // For each file, extract symbols and add them to results - for file in files.iter() { - let file_symbols = symbols_for_file(db, *file, &options); - - for symbol in file_symbols { - results.push(WorkspaceSymbolInfo { - symbol: symbol.clone(), - file: *file, - }); - } + rayon::scope(move |s| { + // For each file, extract symbols and add them to results + for file in files.iter() { + let db = db.dyn_clone(); + s.spawn(move |_| { + for symbol in symbols_for_file(&*db, *file, options) { + // It seems like we could do better here than + // locking `results` for every single symbol, + // but this works pretty well as it is. + results.lock().unwrap().push(WorkspaceSymbolInfo { + symbol: symbol.clone(), + file: *file, + }); + } + }); + } + }); } - results + results.into_inner().unwrap() } /// A symbol found in the workspace, including the file it was found in.