summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorkennytm <kennytm@gmail.com>2019-02-06 00:28:46 +0900
committerGitHub <noreply@github.com>2019-02-06 00:28:46 +0900
commita1ec22f6dd4952806121f27d312417aec9ecb796 (patch)
tree6f8679a7e47d506477b1de65835fa0c7ca378f39 /src/libsyntax
parentb2c6b8c29f13f8d1f242da89e587960b95337819 (diff)
parent1a183368082ad357b1fef0f55038becc9ac14b7b (diff)
downloadrust-a1ec22f6dd4952806121f27d312417aec9ecb796.tar.gz
rust-a1ec22f6dd4952806121f27d312417aec9ecb796.zip
Rollup merge of #58001 - pnkfelix:issue-57735-proc-macro-with-large-tokenstream-slow, r=eddyb
proc_macro: make `TokenStream::from_streams` pre-allocate its vector.

This requires a pre-pass over the input streams. But that is cheap compared to the quadratic blowup associated with reallocating the accumulating vector on-the-fly.

Fix #57735
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/tokenstream.rs8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index f5d2d6f18ee..7d6ffceb2c0 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -255,7 +255,13 @@ impl TokenStream {
             0 => TokenStream::empty(),
             1 => streams.pop().unwrap(),
             _ => {
-                let mut vec = vec![];
+                // rust-lang/rust#57735: pre-allocate vector to avoid
+                // quadratic blow-up due to on-the-fly reallocations.
+                let tree_count = streams.iter()
+                    .map(|ts| match &ts.0 { None => 0, Some(s) => s.len() })
+                    .sum();
+                let mut vec = Vec::with_capacity(tree_count);
+
                 for stream in streams {
                     match stream.0 {
                         None => {},