From b717c74823256d439855bad453a08710e5731a31 Mon Sep 17 00:00:00 2001 From: Lukas Wirth Date: Sun, 28 Dec 2025 11:18:43 +0100 Subject: [PATCH] perf: Pre-allocate some buffers in parsing --- src/tools/rust-analyzer/crates/parser/src/input.rs | 2 +- src/tools/rust-analyzer/crates/parser/src/lexed_str.rs | 7 ++++++- src/tools/rust-analyzer/crates/parser/src/parser.rs | 2 +- src/tools/rust-analyzer/crates/span/src/ast_id.rs | 5 +++-- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/tools/rust-analyzer/crates/parser/src/input.rs b/src/tools/rust-analyzer/crates/parser/src/input.rs index 57eeb431cdc2..42e8a400edd1 100644 --- a/src/tools/rust-analyzer/crates/parser/src/input.rs +++ b/src/tools/rust-analyzer/crates/parser/src/input.rs @@ -97,7 +97,7 @@ fn bit_index(&self, n: usize) -> (usize, usize) { let b_idx = n % (bits::BITS as usize); (idx, b_idx) } - fn len(&self) -> usize { + pub fn len(&self) -> usize { self.kind.len() } } diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs index 7c78ba8faf5f..d7eec6cde8c0 100644 --- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs +++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs @@ -150,7 +150,12 @@ struct Converter<'a> { impl<'a> Converter<'a> { fn new(edition: Edition, text: &'a str) -> Self { Self { - res: LexedStr { text, kind: Vec::new(), start: Vec::new(), error: Vec::new() }, + res: LexedStr { + text, + kind: Vec::with_capacity(text.len() / 3), + start: Vec::with_capacity(text.len() / 3), + error: Vec::new(), + }, offset: 0, edition, } diff --git a/src/tools/rust-analyzer/crates/parser/src/parser.rs b/src/tools/rust-analyzer/crates/parser/src/parser.rs index c41bd593c6a2..4557078de991 100644 --- a/src/tools/rust-analyzer/crates/parser/src/parser.rs +++ b/src/tools/rust-analyzer/crates/parser/src/parser.rs @@ -32,7 +32,7 @@ pub(crate) struct Parser<'t> { impl<'t> Parser<'t> { pub(super) fn new(inp: &'t Input) -> Parser<'t> { - Parser { inp, pos: 0, events: Vec::new(), steps: Cell::new(0) } + Parser { inp, pos: 0, events: Vec::with_capacity(2 * inp.len()), steps: Cell::new(0) } } pub(crate) fn finish(self) -> Vec { diff --git a/src/tools/rust-analyzer/crates/span/src/ast_id.rs b/src/tools/rust-analyzer/crates/span/src/ast_id.rs index e54e0bd2fcc6..3bf14dea75b3 100644 --- a/src/tools/rust-analyzer/crates/span/src/ast_id.rs +++ b/src/tools/rust-analyzer/crates/span/src/ast_id.rs @@ -603,8 +603,9 @@ pub fn from_source(node: &SyntaxNode) -> AstIdMap { // After all, the block will then contain the *outer* item, so we allocate // an ID for it anyway. let mut blocks = Vec::new(); - let mut curr_layer = vec![(node.clone(), None)]; - let mut next_layer = vec![]; + let mut curr_layer = Vec::with_capacity(32); + curr_layer.push((node.clone(), None)); + let mut next_layer = Vec::with_capacity(32); while !curr_layer.is_empty() { curr_layer.drain(..).for_each(|(node, parent_idx)| { let mut preorder = node.preorder();