From 10db1be900130a595b4e195fffc8f9e394a8ddf5 Mon Sep 17 00:00:00 2001 From: Eh2406 Date: Fri, 2 Mar 2018 17:56:36 -0500 Subject: [PATCH] Cache the query result. In a test on https://github.com/rust-lang/cargo/issues/4810#issuecomment-357553286 Before we got to 1700000 ticks in ~97 sec After we got to 1700000 ticks in ~92 sec And query disappears from the flame graph --- src/cargo/core/dependency.rs | 8 ++++---- src/cargo/core/resolver/mod.rs | 30 +++++++++++++++++++++--------- src/cargo/util/cfg.rs | 4 ++-- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/cargo/core/dependency.rs b/src/cargo/core/dependency.rs index aa24554e7..122f060ea 100644 --- a/src/cargo/core/dependency.rs +++ b/src/cargo/core/dependency.rs @@ -12,13 +12,13 @@ use util::errors::{CargoResult, CargoResultExt, CargoError}; /// Information about a dependency requested by a Cargo manifest. /// Cheap to copy. -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug)] pub struct Dependency { inner: Rc, } /// The data underlying a Dependency. -#[derive(PartialEq, Clone, Debug)] +#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug)] struct Inner { name: String, source_id: SourceId, @@ -38,7 +38,7 @@ struct Inner { platform: Option, } -#[derive(Clone, Debug, PartialEq)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug)] pub enum Platform { Name(String), Cfg(CfgExpr), @@ -76,7 +76,7 @@ impl ser::Serialize for Dependency { } } -#[derive(PartialEq, Clone, Debug, Copy)] +#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Debug, Copy)] pub enum Kind { Normal, Development, diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index 54e8517f4..44e9124d5 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -1231,13 +1231,8 @@ impl<'a> Context<'a> { // Next, transform all dependencies into a list of possible candidates // which can satisfy that dependency. let mut deps = deps.into_iter().map(|(dep, features)| { - let mut candidates = self.query(registry, &dep)?; - // When we attempt versions for a package, we'll want to start at - // the maximum version and work our way down. - candidates.sort_by(|a, b| { - b.summary.version().cmp(a.summary.version()) - }); - Ok((dep, Rc::new(candidates), Rc::new(features))) + let candidates = self.query(registry, &dep)?; + Ok((dep, candidates, Rc::new(features))) }).collect::>>()?; // Attempt to resolve dependencies with fewer candidates before trying @@ -1257,7 +1252,13 @@ impl<'a> Context<'a> { /// return. fn query(&self, registry: &mut Registry, - dep: &Dependency) -> CargoResult> { + dep: &Dependency) -> CargoResult>> { + use ::std::cell::RefCell; + thread_local!(static CACHE: RefCell>>> = RefCell::new(BTreeMap::new())); + if let Some(out) = CACHE.with(|m| m.borrow().get(dep).cloned()) { + return Ok(out); + } + let mut ret = Vec::new(); registry.query(dep, &mut |s| { ret.push(Candidate { summary: s, replace: None }); @@ -1318,7 +1319,18 @@ impl<'a> Context<'a> { candidate.replace = replace; } - Ok(ret) + + // When we attempt versions for a package, we'll want to start at + // the maximum version and work our way down. + ret.sort_unstable_by(|a, b| { + b.summary.version().cmp(a.summary.version()) + }); + + let out = Rc::new(ret); + + CACHE.with(|m| m.borrow_mut().insert(dep.clone(), out.clone())); + + Ok(out) } fn prev_active(&self, dep: &Dependency) -> &[Summary] { diff --git a/src/cargo/util/cfg.rs b/src/cargo/util/cfg.rs index 8307ef75c..847d00df1 100644 --- a/src/cargo/util/cfg.rs +++ b/src/cargo/util/cfg.rs @@ -4,13 +4,13 @@ use std::fmt; use util::{CargoError, CargoResult}; -#[derive(Clone, PartialEq, Debug)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug)] pub enum Cfg { Name(String), KeyPair(String, String), } -#[derive(Clone, PartialEq, Debug)] +#[derive(Eq, PartialEq, Ord, PartialOrd, Clone, Debug)] pub enum CfgExpr { Not(Box), All(Vec), -- 2.30.2