Skip to content

Commit

Permalink
Optimize local linkchecker program
Browse files Browse the repository at this point in the history
I noticed on a [recent build][1] that the linkchecker stage of CI took a
whopping 15 minutes of CI time for something that should be near
instantaneous. Some local profiling showed some very hot functions and
clones which were pretty easy to remove, and now instead of running in
minutes locally it runs in seconds.

[1]: https://ci.appveyor.com/project/rust-lang/rust/build/job/kptifw1kb1nm4xuu
  • Loading branch information
alexcrichton committed Nov 29, 2018
1 parent 3e90a12 commit 225140e
Showing 1 changed file with 19 additions and 19 deletions.
38 changes: 19 additions & 19 deletions src/tools/linkchecker/main.rs
Expand Up @@ -24,12 +24,12 @@
//! A few whitelisted exceptions are allowed as there's known bugs in rustdoc,
//! but this should catch the majority of "broken link" cases.

use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::env;
use std::fs::File;
use std::io::prelude::*;
use std::fs;
use std::path::{Path, PathBuf, Component};
use std::collections::{HashMap, HashSet};
use std::collections::hash_map::Entry;
use std::rc::Rc;

use Redirect::*;

Expand Down Expand Up @@ -63,7 +63,7 @@ enum Redirect {
}

struct FileEntry {
source: String,
source: Rc<String>,
ids: HashSet<String>,
}

Expand Down Expand Up @@ -113,7 +113,7 @@ fn walk(cache: &mut Cache, root: &Path, dir: &Path, errors: &mut bool) {
let entry = cache.get_mut(&pretty_path).unwrap();
// we don't need the source anymore,
// so drop to reduce memory-usage
entry.source = String::new();
entry.source = Rc::new(String::new());
}
}
}
Expand Down Expand Up @@ -287,24 +287,24 @@ fn load_file(cache: &mut Cache,
root: &Path,
file: &Path,
redirect: Redirect)
-> Result<(PathBuf, String), LoadError> {
let mut contents = String::new();
-> Result<(PathBuf, Rc<String>), LoadError> {
let pretty_file = PathBuf::from(file.strip_prefix(root).unwrap_or(&file));

let maybe_redirect = match cache.entry(pretty_file.clone()) {
let (maybe_redirect, contents) = match cache.entry(pretty_file.clone()) {
Entry::Occupied(entry) => {
contents = entry.get().source.clone();
None
(None, entry.get().source.clone())
}
Entry::Vacant(entry) => {
let mut fp = File::open(file).map_err(|err| {
if let FromRedirect(true) = redirect {
LoadError::BrokenRedirect(file.to_path_buf(), err)
} else {
LoadError::IOError(err)
let contents = match fs::read_to_string(file) {
Ok(s) => Rc::new(s),
Err(err) => {
return Err(if let FromRedirect(true) = redirect {
LoadError::BrokenRedirect(file.to_path_buf(), err)
} else {
LoadError::IOError(err)
})
}
})?;
fp.read_to_string(&mut contents).map_err(|err| LoadError::IOError(err))?;
};

let maybe = maybe_redirect(&contents);
if maybe.is_some() {
Expand All @@ -317,7 +317,7 @@ fn load_file(cache: &mut Cache,
ids: HashSet::new(),
});
}
maybe
(maybe, contents)
}
};
match maybe_redirect.map(|url| file.parent().unwrap().join(url)) {
Expand Down

0 comments on commit 225140e

Please sign in to comment.