Skip to content

Commit b80a566

Browse files
committed
Auto merge of #4520 - goffrie:master, r=alexcrichton
Don't visit the same unit multiple times. This fixes some accidentally-exponential behaviour we were seeing in our fairly large workspace. It brings a no-op cargo run from about 10 seconds to 0.3 seconds on my machine. Also changes an association list to a hashmap because that was showing up in profiles too.
2 parents a5b734d + 6e53b55 commit b80a566

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

src/cargo/core/package.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ impl hash::Hash for Package {
162162
}
163163

164164
pub struct PackageSet<'cfg> {
165-
packages: Vec<(PackageId, LazyCell<Package>)>,
165+
packages: HashMap<PackageId, LazyCell<Package>>,
166166
sources: RefCell<SourceMap<'cfg>>,
167167
}
168168

@@ -178,14 +178,13 @@ impl<'cfg> PackageSet<'cfg> {
178178
}
179179

180180
pub fn package_ids<'a>(&'a self) -> Box<Iterator<Item=&'a PackageId> + 'a> {
181-
Box::new(self.packages.iter().map(|&(ref p, _)| p))
181+
Box::new(self.packages.keys())
182182
}
183183

184184
pub fn get(&self, id: &PackageId) -> CargoResult<&Package> {
185-
let slot = self.packages.iter().find(|p| p.0 == *id).ok_or_else(|| {
185+
let slot = self.packages.get(id).ok_or_else(|| {
186186
internal(format!("couldn't find `{}` in package set", id))
187187
})?;
188-
let slot = &slot.1;
189188
if let Some(pkg) = slot.borrow() {
190189
return Ok(pkg)
191190
}

src/cargo/ops/cargo_rustc/context.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,13 +194,14 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
194194
/// all the units mentioned in `units`.
195195
pub fn probe_target_info(&mut self, units: &[Unit<'a>]) -> CargoResult<()> {
196196
let mut crate_types = BTreeSet::new();
197+
let mut visited_units = HashSet::new();
197198
// pre-fill with `bin` for learning about tests (nothing may be
198199
// explicitly `bin`) as well as `rlib` as it's the coalesced version of
199200
// `lib` in the compiler and we're not sure which we'll see.
200201
crate_types.insert("bin".to_string());
201202
crate_types.insert("rlib".to_string());
202203
for unit in units {
203-
self.visit_crate_type(unit, &mut crate_types)?;
204+
self.visit_crate_type(unit, &mut crate_types, &mut visited_units)?;
204205
}
205206
debug!("probe_target_info: crate_types={:?}", crate_types);
206207
self.probe_target_info_kind(&crate_types, Kind::Target)?;
@@ -214,8 +215,12 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
214215

215216
fn visit_crate_type(&self,
216217
unit: &Unit<'a>,
217-
crate_types: &mut BTreeSet<String>)
218+
crate_types: &mut BTreeSet<String>,
219+
visited_units: &mut HashSet<Unit<'a>>)
218220
-> CargoResult<()> {
221+
if !visited_units.insert(*unit) {
222+
return Ok(());
223+
}
219224
for target in unit.pkg.manifest().targets() {
220225
crate_types.extend(target.rustc_crate_types().iter().map(|s| {
221226
if *s == "lib" {
@@ -226,7 +231,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> {
226231
}));
227232
}
228233
for dep in self.dep_targets(&unit)? {
229-
self.visit_crate_type(&dep, crate_types)?;
234+
self.visit_crate_type(&dep, crate_types, visited_units)?;
230235
}
231236
Ok(())
232237
}

0 commit comments

Comments
 (0)