[ty] Parallelize workspace symbols

This is a pretty naive approach, but it makes cold times for listing
workspace symbols in home-assistant under 1s on my machine.

Courtesy of Micha:
https://github.com/astral-sh/ruff/pull/20030#discussion_r2292924171
This commit is contained in:
Andrew Gallant 2025-08-22 09:07:30 -04:00 committed by Andrew Gallant
parent fb2d0af18c
commit f407f12f4c
3 changed files with 26 additions and 13 deletions

1
Cargo.lock generated
View file

@ -4243,6 +4243,7 @@ dependencies = [
"bitflags 2.9.2", "bitflags 2.9.2",
"insta", "insta",
"itertools 0.14.0", "itertools 0.14.0",
"rayon",
"regex", "regex",
"ruff_db", "ruff_db",
"ruff_memory_usage", "ruff_memory_usage",

View file

@ -23,6 +23,7 @@ ty_python_semantic = { workspace = true }
ty_project = { workspace = true, features = ["testing"] } ty_project = { workspace = true, features = ["testing"] }
itertools = { workspace = true } itertools = { workspace = true }
rayon = { workspace = true }
regex = { workspace = true } regex = { workspace = true }
rustc-hash = { workspace = true } rustc-hash = { workspace = true }
salsa = { workspace = true, features = ["compact_str"] } salsa = { workspace = true, features = ["compact_str"] }

View file

@ -10,7 +10,6 @@ pub fn workspace_symbols(db: &dyn Db, query: &str) -> Vec<WorkspaceSymbolInfo> {
return Vec::new(); return Vec::new();
} }
let mut results = Vec::new();
let project = db.project(); let project = db.project();
let options = SymbolsOptions { let options = SymbolsOptions {
@ -19,22 +18,34 @@ pub fn workspace_symbols(db: &dyn Db, query: &str) -> Vec<WorkspaceSymbolInfo> {
query_string: Some(query.into()), query_string: Some(query.into()),
}; };
// Get all files in the project
let files = project.files(db); 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 rayon::scope(move |s| {
for file in files.iter() { // For each file, extract symbols and add them to results
let file_symbols = symbols_for_file(db, *file, &options); for file in files.iter() {
let db = db.dyn_clone();
for symbol in file_symbols { s.spawn(move |_| {
results.push(WorkspaceSymbolInfo { for symbol in symbols_for_file(&*db, *file, options) {
symbol: symbol.clone(), // It seems like we could do better here than
file: *file, // 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. /// A symbol found in the workspace, including the file it was found in.