]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Preallocate when building the dep graph
authorAlex Crichton <alex@alexcrichton.com>
Fri, 15 Sep 2017 04:28:55 +0000 (21:28 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 15 Sep 2017 04:28:55 +0000 (21:28 -0700)
This commit alters the `query` function in the dep graph module to preallocate
memory using `with_capacity` instead of relying on automatic growth. Discovered
in #44576 it was found that for the syntex_syntax clean incremental benchmark
the peak memory usage was found when the dep graph was being saved, particularly
the `DepGraphQuery` data structure itself. PRs like #44142 which add more
queries end up just making this much larger!

I didn't see an immediately obvious way to reduce the size of the
`DepGraphQuery` object, but it turns out that `with_capacity` helps quite a bit!
Locally 831 MB was used [before] this commit, and 770 MB is in use at the peak
of the compiler [after] this commit. That's a nice 7.5% improvement! This won't
quite make up for the losses in #44142 but I figured it's a good start.

[before]: https://gist.github.com/alexcrichton/2d2b9c7a65503761925c5a0bcfeb0d1e
[before]: https://gist.github.com/alexcrichton/6da51f2a6184bfb81694cc44f06deb5b

src/librustc/dep_graph/query.rs
src/librustc_data_structures/graph/mod.rs
src/librustc_data_structures/snapshot_vec.rs

index 283da1050aedc8393c1d6ca7057ba5d39f846d3a..ea83a4f8b3104dd2de1113fa6eba381d1d043444 100644 (file)
@@ -22,11 +22,10 @@ impl DepGraphQuery {
     pub fn new(nodes: &[DepNode],
                edges: &[(DepNode, DepNode)])
                -> DepGraphQuery {
-        let mut graph = Graph::new();
+        let mut graph = Graph::with_capacity(nodes.len(), edges.len());
         let mut indices = FxHashMap();
         for node in nodes {
-            indices.insert(node.clone(), graph.next_node_index());
-            graph.add_node(node.clone());
+            indices.insert(node.clone(), graph.add_node(node.clone()));
         }
 
         for &(ref source, ref target) in edges {
index a5f83ce05f5e5108e84ce29a08ee7668cb18601f..474622f3669131a0c54623a53376a8e942f3d864 100644 (file)
@@ -114,6 +114,13 @@ pub fn new() -> Graph<N, E> {
         }
     }
 
+    pub fn with_capacity(nodes: usize, edges: usize) -> Graph<N, E> {
+        Graph {
+            nodes: SnapshotVec::with_capacity(nodes),
+            edges: SnapshotVec::with_capacity(edges),
+        }
+    }
+
     // # Simple accessors
 
     #[inline]
index dac074ab91e1bfe11c67876f0d3dce2bc7bfc492..2da91918288bab77ff8266086a662ea150fc4aad 100644 (file)
@@ -66,6 +66,13 @@ pub fn new() -> SnapshotVec<D> {
         }
     }
 
+    pub fn with_capacity(n: usize) -> SnapshotVec<D> {
+        SnapshotVec {
+            values: Vec::with_capacity(n),
+            undo_log: Vec::new(),
+        }
+    }
+
     fn in_snapshot(&self) -> bool {
         !self.undo_log.is_empty()
     }