Skip to content

Commit 366b913

Browse files
committed
Reduce token cloning in core methods
I've been sitting around a 10% improvement with each added commit not moving the needled all that much. Then after poking a bit harder at Instruments I realized that some super hot paths are in the token manipulation methods themselves. This adds an 18% improvement against my previous commit which gives a grand total of about 28% on both benchmarks.
1 parent 86467ce commit 366b913

File tree

1 file changed

+21
-11
lines changed

1 file changed

+21
-11
lines changed

src/parser/mod.rs

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3474,20 +3474,30 @@ impl<'a> Parser<'a> {
34743474
/// true. Otherwise, no tokens are consumed and returns false.
34753475
#[must_use]
34763476
pub fn parse_keyword(&mut self, expected: Keyword) -> bool {
3477-
self.parse_keyword_token(expected).is_some()
3477+
if self.peek_keyword(expected) {
3478+
self.next_token_ref();
3479+
true
3480+
} else {
3481+
false
3482+
}
34783483
}
34793484

34803485
#[must_use]
34813486
pub fn parse_keyword_token(&mut self, expected: Keyword) -> Option<TokenWithSpan> {
3482-
match self.peek_token().token {
3483-
Token::Word(w) if expected == w.keyword => Some(self.next_token()),
3487+
self.parse_keyword_token_ref(expected).cloned()
3488+
}
3489+
3490+
#[must_use]
3491+
pub fn parse_keyword_token_ref(&mut self, expected: Keyword) -> Option<&TokenWithSpan> {
3492+
match &self.peek_token_ref().token {
3493+
Token::Word(w) if expected == w.keyword => Some(self.next_token_ref()),
34843494
_ => None,
34853495
}
34863496
}
34873497

34883498
#[must_use]
34893499
pub fn peek_keyword(&mut self, expected: Keyword) -> bool {
3490-
matches!(self.peek_token().token, Token::Word(w) if expected == w.keyword)
3500+
matches!(&self.peek_token_ref().token, Token::Word(w) if expected == w.keyword)
34913501
}
34923502

34933503
/// If the current token is the `expected` keyword followed by
@@ -3568,10 +3578,10 @@ impl<'a> Parser<'a> {
35683578
/// If the current token is the `expected` keyword, consume the token.
35693579
/// Otherwise, return an error.
35703580
pub fn expect_keyword(&mut self, expected: Keyword) -> Result<TokenWithSpan, ParserError> {
3571-
if let Some(token) = self.parse_keyword_token(expected) {
3572-
Ok(token)
3581+
if let Some(token) = self.parse_keyword_token_ref(expected) {
3582+
Ok(token.clone())
35733583
} else {
3574-
self.expected(format!("{:?}", &expected).as_str(), self.peek_token())
3584+
self.expected_current(format!("{:?}", &expected).as_str())
35753585
}
35763586
}
35773587

@@ -3587,8 +3597,8 @@ impl<'a> Parser<'a> {
35873597
/// Consume the next token if it matches the expected token, otherwise return false
35883598
#[must_use]
35893599
pub fn consume_token(&mut self, expected: &Token) -> bool {
3590-
if self.peek_token() == *expected {
3591-
self.next_token();
3600+
if self.peek_token_ref() == expected {
3601+
self.next_token_ref();
35923602
true
35933603
} else {
35943604
false
@@ -9137,9 +9147,9 @@ impl<'a> Parser<'a> {
91379147
/// expect the initial keyword to be already consumed
91389148
pub fn parse_query(&mut self) -> Result<Box<Query>, ParserError> {
91399149
let _guard = self.recursion_counter.try_decrease()?;
9140-
let with = if let Some(with_token) = self.parse_keyword_token(Keyword::WITH) {
9150+
let with = if let Some(with_token) = self.parse_keyword_token_ref(Keyword::WITH) {
91419151
Some(With {
9142-
with_token: with_token.into(),
9152+
with_token: with_token.clone().into(),
91439153
recursive: self.parse_keyword(Keyword::RECURSIVE),
91449154
cte_tables: self.parse_comma_separated(Parser::parse_cte)?,
91459155
})

0 commit comments

Comments
 (0)