From a7817dd52cb3f830504cdf702f726a0c0b7685dd Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 14 Sep 2017 21:28:55 -0700 Subject: [PATCH] rustc: Preallocate when building the dep graph 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 | 5 ++--- src/librustc_data_structures/graph/mod.rs | 7 +++++++ src/librustc_data_structures/snapshot_vec.rs | 7 +++++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/librustc/dep_graph/query.rs b/src/librustc/dep_graph/query.rs index 283da1050aedc..ea83a4f8b3104 100644 --- a/src/librustc/dep_graph/query.rs +++ b/src/librustc/dep_graph/query.rs @@ -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 { diff --git a/src/librustc_data_structures/graph/mod.rs b/src/librustc_data_structures/graph/mod.rs index a5f83ce05f5e5..474622f366913 100644 --- a/src/librustc_data_structures/graph/mod.rs +++ b/src/librustc_data_structures/graph/mod.rs @@ -114,6 +114,13 @@ impl Graph { } } + pub fn with_capacity(nodes: usize, edges: usize) -> Graph { + Graph { + nodes: SnapshotVec::with_capacity(nodes), + edges: SnapshotVec::with_capacity(edges), + } + } + // # Simple accessors #[inline] diff --git a/src/librustc_data_structures/snapshot_vec.rs b/src/librustc_data_structures/snapshot_vec.rs index dac074ab91e1b..2da91918288ba 100644 --- a/src/librustc_data_structures/snapshot_vec.rs +++ b/src/librustc_data_structures/snapshot_vec.rs @@ -66,6 +66,13 @@ impl SnapshotVec { } } + pub fn with_capacity(n: usize) -> SnapshotVec { + SnapshotVec { + values: Vec::with_capacity(n), + undo_log: Vec::new(), + } + } + fn in_snapshot(&self) -> bool { !self.undo_log.is_empty() }