intern the features
authorEh2406 <YeomanYaacov@gmail.com>
Sun, 4 Mar 2018 03:38:10 +0000 (22:38 -0500)
committerEh2406 <YeomanYaacov@gmail.com>
Tue, 6 Mar 2018 20:39:10 +0000 (15:39 -0500)
In a test on https://github.com/rust-lang/cargo/issues/4810#issuecomment-357553286
Before we got to 5000000 ticks in ~65 sec
After we got to 5000000 ticks in ~52 sec

src/cargo/core/interning.rs
src/cargo/core/resolver/mod.rs

index 82b6830ee1ab239a87f012c424522404dd78634a..c24b6e70f8108dbbfc24e4e4526a9ae61be276cf 100644 (file)
@@ -22,9 +22,9 @@ impl InternedString {
         id_from_str.insert(str.to_string(), str_from_id.len() - 1);
         return InternedString { id: str_from_id.len() - 1 }
     }
-//    pub fn to_inner(&self) -> String {
-//        STRING_CASHE.read().unwrap().0[self.id].to_string()
-//    }
+    pub fn to_inner(&self) -> String {
+        STRING_CASHE.read().unwrap().0[self.id].to_string()
+    }
 }
 
 impl fmt::Debug for InternedString {
index 49537d676aba5cf22b12906f796be529d94e91cd..361f3f951a2cbee85c5d393a3d75de3a850af76f 100644 (file)
@@ -332,7 +332,7 @@ struct Context {
     //       switch to persistent hash maps if we can at some point or otherwise
     //       make these much cheaper to clone in general.
     activations: Activations,
-    resolve_features: HashMap<PackageId, HashSet<String>>,
+    resolve_features: HashMap<PackageId, HashSet<InternedString>>,
     links: HashMap<String, PackageId>,
 
     // These are two cheaply-cloneable lists (O(1) clone) which are effectively
@@ -371,7 +371,7 @@ pub fn resolve(summaries: &[(Summary, Method)],
         metadata: BTreeMap::new(),
         replacements: cx.resolve_replacements(),
         features: cx.resolve_features.iter().map(|(k, v)| {
-            (k.clone(), v.clone())
+            (k.clone(), v.iter().map(|x| x.to_inner()).collect())
         }).collect(),
         unused_patches: Vec::new(),
     };
@@ -1318,8 +1318,8 @@ impl Context {
         let has_default_feature = summary.features().contains_key("default");
         Ok(match self.resolve_features.get(id) {
             Some(prev) => {
-                features.iter().all(|f| prev.contains(f)) &&
-                    (!use_default || prev.contains("default") ||
+                features.iter().all(|f| prev.contains(&InternedString::new(f))) &&
+                    (!use_default || prev.contains(&InternedString::new("default")) ||
                      !has_default_feature)
             }
             None => features.is_empty() && (!use_default || !has_default_feature)
@@ -1434,9 +1434,7 @@ impl Context {
             let set = self.resolve_features.entry(pkgid.clone())
                               .or_insert_with(HashSet::new);
             for feature in reqs.used {
-                if !set.contains(feature) {
-                    set.insert(feature.to_string());
-                }
+                set.insert(InternedString::new(feature));
             }
         }