Skip to content

Commit 3aaf07b

Browse files
Add more profiling for flyimports
1 parent f4da4de commit 3aaf07b

File tree

6 files changed

+92
-71
lines changed

6 files changed

+92
-71
lines changed

crates/base_db/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ impl<T: SourceDatabaseExt> FileLoader for FileLoaderDelegate<&'_ T> {
120120
}
121121

122122
fn relevant_crates(&self, file_id: FileId) -> Arc<FxHashSet<CrateId>> {
123+
let _p = profile::span("relevant_crates");
123124
let source_root = self.0.file_source_root(file_id);
124125
self.0.source_root_crates(source_root)
125126
}

crates/hir/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ impl Crate {
191191
db: &dyn DefDatabase,
192192
query: import_map::Query,
193193
) -> impl Iterator<Item = Either<ModuleDef, MacroDef>> {
194+
let _p = profile::span("query_external_importables");
194195
import_map::search_dependencies(db, self.into(), query).into_iter().map(|item| match item {
195196
ItemInNs::Types(mod_id) | ItemInNs::Values(mod_id) => Either::Left(mod_id.into()),
196197
ItemInNs::Macros(mac_id) => Either::Right(mac_id.into()),
@@ -2185,6 +2186,7 @@ impl Type {
21852186
name: Option<&Name>,
21862187
mut callback: impl FnMut(&Ty, Function) -> Option<T>,
21872188
) -> Option<T> {
2189+
let _p = profile::span("iterate_method_candidates");
21882190
// There should be no inference vars in types passed here
21892191
// FIXME check that?
21902192
// FIXME replace Unknown by bound vars here
@@ -2218,6 +2220,7 @@ impl Type {
22182220
name: Option<&Name>,
22192221
mut callback: impl FnMut(&Ty, AssocItem) -> Option<T>,
22202222
) -> Option<T> {
2223+
let _p = profile::span("iterate_path_candidates");
22212224
let canonical = hir_ty::replace_errors_with_variables(&self.ty);
22222225

22232226
let env = self.env.clone();
@@ -2255,6 +2258,7 @@ impl Type {
22552258
&'a self,
22562259
db: &'a dyn HirDatabase,
22572260
) -> impl Iterator<Item = Trait> + 'a {
2261+
let _p = profile::span("applicable_inherent_traits");
22582262
self.autoderef(db)
22592263
.filter_map(|derefed_type| derefed_type.ty.dyn_trait())
22602264
.flat_map(move |dyn_trait_id| hir_ty::all_super_traits(db.upcast(), dyn_trait_id))

crates/hir_def/src/import_map.rs

Lines changed: 82 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -69,80 +69,10 @@ pub struct ImportMap {
6969
impl ImportMap {
7070
pub fn import_map_query(db: &dyn DefDatabase, krate: CrateId) -> Arc<Self> {
7171
let _p = profile::span("import_map_query");
72-
let def_map = db.crate_def_map(krate);
73-
let mut import_map = Self::default();
74-
75-
// We look only into modules that are public(ly reexported), starting with the crate root.
76-
let empty = ImportPath { segments: vec![] };
77-
let root = def_map.module_id(def_map.root());
78-
let mut worklist = vec![(root, empty)];
79-
while let Some((module, mod_path)) = worklist.pop() {
80-
let ext_def_map;
81-
let mod_data = if module.krate == krate {
82-
&def_map[module.local_id]
83-
} else {
84-
// The crate might reexport a module defined in another crate.
85-
ext_def_map = module.def_map(db);
86-
&ext_def_map[module.local_id]
87-
};
88-
89-
let visible_items = mod_data.scope.entries().filter_map(|(name, per_ns)| {
90-
let per_ns = per_ns.filter_visibility(|vis| vis == Visibility::Public);
91-
if per_ns.is_none() {
92-
None
93-
} else {
94-
Some((name, per_ns))
95-
}
96-
});
9772

98-
for (name, per_ns) in visible_items {
99-
let mk_path = || {
100-
let mut path = mod_path.clone();
101-
path.segments.push(name.clone());
102-
path
103-
};
104-
105-
for item in per_ns.iter_items() {
106-
let path = mk_path();
107-
let path_len = path.len();
108-
let import_info =
109-
ImportInfo { path, container: module, is_trait_assoc_item: false };
110-
111-
if let Some(ModuleDefId::TraitId(tr)) = item.as_module_def_id() {
112-
import_map.collect_trait_assoc_items(
113-
db,
114-
tr,
115-
matches!(item, ItemInNs::Types(_)),
116-
&import_info,
117-
);
118-
}
119-
120-
match import_map.map.entry(item) {
121-
Entry::Vacant(entry) => {
122-
entry.insert(import_info);
123-
}
124-
Entry::Occupied(mut entry) => {
125-
// If the new path is shorter, prefer that one.
126-
if path_len < entry.get().path.len() {
127-
*entry.get_mut() = import_info;
128-
} else {
129-
continue;
130-
}
131-
}
132-
}
133-
134-
// If we've just added a path to a module, descend into it. We might traverse
135-
// modules multiple times, but only if the new path to it is shorter than the
136-
// first (else we `continue` above).
137-
if let Some(ModuleDefId::ModuleId(mod_id)) = item.as_module_def_id() {
138-
worklist.push((mod_id, mk_path()));
139-
}
140-
}
141-
}
142-
}
73+
let mut import_map = collect_import_map(db, krate);
14374

14475
let mut importables = import_map.map.iter().collect::<Vec<_>>();
145-
14676
importables.sort_by(cmp);
14777

14878
// Build the FST, taking care not to insert duplicate values.
@@ -185,6 +115,7 @@ impl ImportMap {
185115
is_type_in_ns: bool,
186116
original_import_info: &ImportInfo,
187117
) {
118+
let _p = profile::span("collect_trait_assoc_items");
188119
for (assoc_item_name, item) in &db.trait_data(tr).items {
189120
let module_def_id = match item {
190121
AssocItemId::FunctionId(f) => ModuleDefId::from(*f),
@@ -210,6 +141,84 @@ impl ImportMap {
210141
}
211142
}
212143

144+
fn collect_import_map(db: &dyn DefDatabase, krate: CrateId) -> ImportMap {
145+
let _p = profile::span("collect_import_map");
146+
147+
let def_map = db.crate_def_map(krate);
148+
let mut import_map = ImportMap::default();
149+
150+
// We look only into modules that are public(ly reexported), starting with the crate root.
151+
let empty = ImportPath { segments: vec![] };
152+
let root = def_map.module_id(def_map.root());
153+
let mut worklist = vec![(root, empty)];
154+
while let Some((module, mod_path)) = worklist.pop() {
155+
let ext_def_map;
156+
let mod_data = if module.krate == krate {
157+
&def_map[module.local_id]
158+
} else {
159+
// The crate might reexport a module defined in another crate.
160+
ext_def_map = module.def_map(db);
161+
&ext_def_map[module.local_id]
162+
};
163+
164+
let visible_items = mod_data.scope.entries().filter_map(|(name, per_ns)| {
165+
let per_ns = per_ns.filter_visibility(|vis| vis == Visibility::Public);
166+
if per_ns.is_none() {
167+
None
168+
} else {
169+
Some((name, per_ns))
170+
}
171+
});
172+
173+
for (name, per_ns) in visible_items {
174+
let mk_path = || {
175+
let mut path = mod_path.clone();
176+
path.segments.push(name.clone());
177+
path
178+
};
179+
180+
for item in per_ns.iter_items() {
181+
let path = mk_path();
182+
let path_len = path.len();
183+
let import_info =
184+
ImportInfo { path, container: module, is_trait_assoc_item: false };
185+
186+
if let Some(ModuleDefId::TraitId(tr)) = item.as_module_def_id() {
187+
import_map.collect_trait_assoc_items(
188+
db,
189+
tr,
190+
matches!(item, ItemInNs::Types(_)),
191+
&import_info,
192+
);
193+
}
194+
195+
match import_map.map.entry(item) {
196+
Entry::Vacant(entry) => {
197+
entry.insert(import_info);
198+
}
199+
Entry::Occupied(mut entry) => {
200+
// If the new path is shorter, prefer that one.
201+
if path_len < entry.get().path.len() {
202+
*entry.get_mut() = import_info;
203+
} else {
204+
continue;
205+
}
206+
}
207+
}
208+
209+
// If we've just added a path to a module, descend into it. We might traverse
210+
// modules multiple times, but only if the new path to it is shorter than the
211+
// first (else we `continue` above).
212+
if let Some(ModuleDefId::ModuleId(mod_id)) = item.as_module_def_id() {
213+
worklist.push((mod_id, mk_path()));
214+
}
215+
}
216+
}
217+
}
218+
219+
import_map
220+
}
221+
213222
impl PartialEq for ImportMap {
214223
fn eq(&self, other: &Self) -> bool {
215224
// `fst` and `importables` are built from `map`, so we don't need to compare them.
@@ -240,6 +249,7 @@ impl fmt::Debug for ImportMap {
240249
}
241250

242251
fn fst_path(path: &ImportPath) -> String {
252+
let _p = profile::span("fst_path");
243253
let mut s = path.to_string();
244254
s.make_ascii_lowercase();
245255
s
@@ -338,6 +348,7 @@ impl Query {
338348
}
339349

340350
fn import_matches(&self, import: &ImportInfo, enforce_lowercase: bool) -> bool {
351+
let _p = profile::span("import_map::Query::import_matches");
341352
if import.is_trait_assoc_item {
342353
if self.exclude_import_kinds.contains(&ImportKind::AssociatedItem) {
343354
return false;

crates/hir_def/src/lang_item.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ impl LangItems {
141141
) where
142142
T: Into<AttrDefId> + Copy,
143143
{
144+
let _p = profile::span("collect_lang_item");
144145
if let Some(lang_item_name) = lang_attr(db, item) {
145146
self.items.entry(lang_item_name).or_insert_with(|| constructor(item));
146147
}

crates/hir_def/src/per_ns.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ impl PerNs {
6262
}
6363

6464
pub fn filter_visibility(self, mut f: impl FnMut(Visibility) -> bool) -> PerNs {
65+
let _p = profile::span("PerNs::filter_visibility");
6566
PerNs {
6667
types: self.types.filter(|(_, v)| f(*v)),
6768
values: self.values.filter(|(_, v)| f(*v)),
@@ -86,6 +87,7 @@ impl PerNs {
8687
}
8788

8889
pub fn iter_items(self) -> impl Iterator<Item = ItemInNs> {
90+
let _p = profile::span("PerNs::iter_items");
8991
self.types
9092
.map(|it| ItemInNs::Types(it.0))
9193
.into_iter()

crates/ide_db/src/symbol_index.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ pub fn world_symbols(db: &RootDatabase, query: Query) -> Vec<FileSymbol> {
197197
}
198198

199199
pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec<FileSymbol> {
200+
let _p = profile::span("crate_symbols").detail(|| format!("{:?}", query));
200201
// FIXME(#4842): This now depends on CrateDefMap, why not build the entire symbol index from
201202
// that instead?
202203

@@ -321,6 +322,7 @@ impl SymbolIndex {
321322

322323
impl Query {
323324
pub(crate) fn search(self, indices: &[&SymbolIndex]) -> Vec<FileSymbol> {
325+
let _p = profile::span("symbol_index::Query::search");
324326
let mut op = fst::map::OpBuilder::new();
325327
for file_symbols in indices.iter() {
326328
let automaton = fst::automaton::Subsequence::new(&self.lowercased);

0 commit comments

Comments
 (0)