Skip to content

Commit aa5a68b

Browse files
committed
Auto merge of #151368 - GuillaumeGomez:librustdoc-perf, r=<try>
Rustdoc performance improvements
2 parents 158ae9e + f660783 commit aa5a68b

File tree

1 file changed

+46
-34
lines changed

1 file changed

+46
-34
lines changed

src/librustdoc/html/render/write_shared.rs

Lines changed: 46 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ use std::str::FromStr;
2626
use std::{fmt, fs};
2727

2828
use indexmap::IndexMap;
29-
use regex::Regex;
3029
use rustc_ast::join_path_syms;
3130
use rustc_data_structures::flock;
3231
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
@@ -376,12 +375,16 @@ fn hack_get_external_crate_names(
376375
};
377376
// this is only run once so it's fine not to cache it
378377
// !dot_matches_new_line: all crates on same line. greedy: match last bracket
379-
let regex = Regex::new(r"\[.*\]").unwrap();
380-
let Some(content) = regex.find(&content) else {
381-
return Err(Error::new("could not find crates list in crates.js", path));
382-
};
383-
let content: Vec<String> = try_err!(serde_json::from_str(content.as_str()), &path);
384-
Ok(content)
378+
379+
if let Some(start) = content.find('[')
380+
&& let Some(end) = content[start..].find(']')
381+
{
382+
let content: Vec<String> =
383+
try_err!(serde_json::from_str(&content[start..=start + end]), &path);
384+
Ok(content)
385+
} else {
386+
Err(Error::new("could not find crates list in crates.js", path))
387+
}
385388
}
386389

387390
#[derive(Serialize, Deserialize, Clone, Default, Debug)]
@@ -488,7 +491,15 @@ impl Hierarchy {
488491
let files = self.elems.borrow();
489492
let name = OrderedJson::serialize(self.elem.to_str().expect("invalid osstring conversion"))
490493
.unwrap();
491-
let mut out = Vec::from([name]);
494+
let needed_capacity = if !files.is_empty() {
495+
3
496+
} else if !subs.is_empty() {
497+
2
498+
} else {
499+
1
500+
};
501+
let mut out = Vec::with_capacity(needed_capacity);
502+
out.push(name);
492503
if !subs.is_empty() || !files.is_empty() {
493504
let subs = subs.iter().map(|(_, s)| s.to_json_string());
494505
out.push(OrderedJson::array_sorted(subs));
@@ -504,33 +515,34 @@ impl Hierarchy {
504515

505516
fn add_path(self: &Rc<Self>, path: &Path) {
506517
let mut h = Rc::clone(self);
507-
let mut elems = path
508-
.components()
509-
.filter_map(|s| match s {
510-
Component::Normal(s) => Some(s.to_owned()),
511-
Component::ParentDir => Some(OsString::from("..")),
512-
_ => None,
513-
})
514-
.peekable();
515-
loop {
516-
let cur_elem = elems.next().expect("empty file path");
517-
if cur_elem == ".." {
518-
if let Some(parent) = h.parent.upgrade() {
519-
h = parent;
518+
let mut components = path.components().peekable();
519+
520+
while let Some(component) = components.next() {
521+
match component {
522+
Component::Normal(s) => {
523+
if components.peek().is_none() {
524+
h.elems.borrow_mut().insert(s.to_owned());
525+
break;
526+
}
527+
let next_h = {
528+
let mut children = h.children.borrow_mut();
529+
530+
if let Some(existing) = children.get(s) {
531+
Rc::clone(existing)
532+
} else {
533+
let new_node = Rc::new(Self::with_parent(s.to_owned(), &h));
534+
children.insert(s.to_owned(), Rc::clone(&new_node));
535+
new_node
536+
}
537+
};
538+
h = next_h;
520539
}
521-
continue;
522-
}
523-
if elems.peek().is_none() {
524-
h.elems.borrow_mut().insert(cur_elem);
525-
break;
526-
} else {
527-
let entry = Rc::clone(
528-
h.children
529-
.borrow_mut()
530-
.entry(cur_elem.clone())
531-
.or_insert_with(|| Rc::new(Self::with_parent(cur_elem, &h))),
532-
);
533-
h = entry;
540+
Component::ParentDir => {
541+
if let Some(parent) = h.parent.upgrade() {
542+
h = parent;
543+
}
544+
}
545+
_ => {}
534546
}
535547
}
536548
}

0 commit comments

Comments
 (0)