From af6086182d98d284e4be72695be18ce3ddcbe671 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Sat, 3 Mar 2018 21:33:23 -0500 Subject: [PATCH] use more Rc in the part of resolver that gets cloned a lot In a test on https://github.com/rust-lang/cargo/issues/4810#issuecomment-357553286 Before we got to 1700000 ticks in ~(82 to 97) sec After we got to 1700000 ticks in ~(63 to 67) sec --- src/cargo/core/resolver/mod.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index 264c32c82e6..b5ca6d9cba4 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -344,7 +344,7 @@ struct Context { warnings: RcList, } -type Activations = HashMap>>; +type Activations = HashMap>>>; /// Builds the list of all packages required to build the first argument. pub fn resolve(summaries: &[(Summary, Method)], @@ -1287,7 +1287,7 @@ impl Context { .entry(id.name().to_string()) .or_insert_with(HashMap::new) .entry(id.source_id().clone()) - .or_insert_with(Vec::new); + .or_insert_with(||Rc::new(Vec::new())); if !prev.iter().any(|c| c == summary) { self.resolve_graph.push(GraphNode::Add(id.clone())); if let Some(link) = summary.links() { @@ -1295,7 +1295,9 @@ impl Context { "Attempting to resolve a with more then one crate with the links={}. \n\ This will not build as is. Consider rebuilding the .lock file.", link); } - prev.push(summary.clone()); + let mut inner: Vec<_> = (**prev).clone(); + inner.push(summary.clone()); + *prev = Rc::new(inner); return Ok(false) } debug!("checking if {} is already activated", summary.package_id()); @@ -1463,7 +1465,7 @@ fn check_cycles(resolve: &Resolve, activations: &Activations) -> CargoResult<()> { let summaries: HashMap<&PackageId, &Summary> = activations.values() .flat_map(|v| v.values()) - .flat_map(|v| v) + .flat_map(|v| v.iter()) .map(|s| (s.package_id(), s)) .collect();