From fe15b14274c3069d85c026ee131d7b7f9b2cac5b Mon Sep 17 00:00:00 2001 From: sssooonnnggg Date: Wed, 3 Jan 2024 19:26:29 +0800 Subject: [PATCH 1/2] perf: use str instead of Cow to reduce Token size --- generator/src/generator.rs | 16 ++-------------- pest/src/iterators/pairs.rs | 24 ++++++++++++------------ pest/src/iterators/queueable_token.rs | 4 +--- pest/src/parser_state.rs | 6 +++--- vm/src/lib.rs | 2 +- 5 files changed, 19 insertions(+), 33 deletions(-) diff --git a/generator/src/generator.rs b/generator/src/generator.rs index d301e43a..7a527c5a 100644 --- a/generator/src/generator.rs +++ b/generator/src/generator.rs @@ -568,14 +568,8 @@ fn generate_expr(expr: OptimizedExpr) -> TokenStream { #[cfg(feature = "grammar-extras")] OptimizedExpr::NodeTag(expr, tag) => { let expr = generate_expr(*expr); - let tag_cow = { - #[cfg(feature = "std")] - quote! { ::std::borrow::Cow::Borrowed(#tag) } - #[cfg(not(feature = "std"))] - quote! { ::alloc::borrow::Cow::Borrowed(#tag) } - }; quote! { - #expr.and_then(|state| state.tag_node(#tag_cow)) + #expr.and_then(|state| state.tag_node(#tag)) } } } @@ -729,14 +723,8 @@ fn generate_expr_atomic(expr: OptimizedExpr) -> TokenStream { #[cfg(feature = "grammar-extras")] OptimizedExpr::NodeTag(expr, tag) => { let expr = generate_expr_atomic(*expr); - let tag_cow = { - #[cfg(feature = "std")] - quote! { ::std::borrow::Cow::Borrowed(#tag) } - #[cfg(not(feature = "std"))] - quote! { ::alloc::borrow::Cow::Borrowed(#tag) } - }; quote! { - #expr.and_then(|state| state.tag_node(#tag_cow)) + #expr.and_then(|state| state.tag_node(#tag)) } } } diff --git a/pest/src/iterators/pairs.rs b/pest/src/iterators/pairs.rs index 805b5a34..ed6a9a13 100644 --- a/pest/src/iterators/pairs.rs +++ b/pest/src/iterators/pairs.rs @@ -227,9 +227,9 @@ impl<'i, R: RuleType> Pairs<'i, R> { /// state: Box>, /// ) -> ParseResult>> { /// expr(state, Rule::mul, "*") - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("mul"))) + /// .and_then(|state| state.tag_node("mul")) /// .or_else(|state| expr(state, Rule::add, "+")) - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("add"))) + /// .and_then(|state| state.tag_node("add")) /// } /// fn expr<'a>( /// state: Box>, @@ -239,10 +239,10 @@ impl<'i, R: RuleType> Pairs<'i, R> { /// state.rule(r, |state| { /// state.sequence(|state| { /// number(state) - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("lhs"))) + /// .and_then(|state| state.tag_node("lhs")) /// .and_then(|state| state.match_string(o)) /// .and_then(number) - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("rhs"))) + /// .and_then(|state| state.tag_node("rhs")) /// }) /// }) /// } @@ -278,9 +278,9 @@ impl<'i, R: RuleType> Pairs<'i, R> { /// state: Box>, /// ) -> ParseResult>> { /// expr(state, Rule::mul, "*") - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("mul"))) + /// .and_then(|state| state.tag_node("mul")) /// .or_else(|state| expr(state, Rule::add, "+")) - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("add"))) + /// .and_then(|state| state.tag_node("add")) /// } /// fn expr<'a>( /// state: Box>, @@ -290,10 +290,10 @@ impl<'i, R: RuleType> Pairs<'i, R> { /// state.rule(r, |state| { /// state.sequence(|state| { /// number(state) - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("lhs"))) + /// .and_then(|state| state.tag_node("lhs")) /// .and_then(|state| state.match_string(o)) /// .and_then(number) - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("rhs"))) + /// .and_then(|state| state.tag_node("rhs")) /// }) /// }) /// } @@ -676,9 +676,9 @@ mod tests { state: Box>, ) -> ParseResult>> { expr(state, Rule::mul, "*") - .and_then(|state| state.tag_node(alloc::borrow::Cow::Borrowed("mul"))) + .and_then(|state| state.tag_node("mul")) .or_else(|state| expr(state, Rule::add, "+")) - .and_then(|state| state.tag_node(alloc::borrow::Cow::Borrowed("add"))) + .and_then(|state| state.tag_node("add")) } fn expr<'a>( state: Box>, @@ -688,10 +688,10 @@ mod tests { state.rule(r, |state| { state.sequence(|state| { number(state) - .and_then(|state| state.tag_node(alloc::borrow::Cow::Borrowed("lhs"))) + .and_then(|state| state.tag_node("lhs")) .and_then(|state| state.match_string(o)) .and_then(number) - .and_then(|state| state.tag_node(alloc::borrow::Cow::Borrowed("rhs"))) + .and_then(|state| state.tag_node("rhs")) }) }) } diff --git a/pest/src/iterators/queueable_token.rs b/pest/src/iterators/queueable_token.rs index 67426092..530742b5 100644 --- a/pest/src/iterators/queueable_token.rs +++ b/pest/src/iterators/queueable_token.rs @@ -7,8 +7,6 @@ // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. -use alloc::borrow::Cow; - // This structure serves to improve performance over Token objects in two ways: // // * it is smaller than a Token, leading to both less memory use when stored in the queue but also @@ -24,7 +22,7 @@ pub enum QueueableToken<'i, R> { End { start_token_index: usize, rule: R, - tag: Option>, + tag: Option<&'i str>, input_pos: usize, }, } diff --git a/pest/src/parser_state.rs b/pest/src/parser_state.rs index 58c9ecb1..f665bf23 100644 --- a/pest/src/parser_state.rs +++ b/pest/src/parser_state.rs @@ -7,7 +7,7 @@ // option. All files in the project carrying such notice may not be copied, // modified, or distributed except according to those terms. -use alloc::borrow::{Cow, ToOwned}; +use alloc::borrow::ToOwned; use alloc::boxed::Box; use alloc::rc::Rc; use alloc::vec; @@ -392,7 +392,7 @@ impl<'i, R: RuleType> ParserState<'i, R> { /// character(state) /// .and_then(|state| character(state)) /// .and_then(|state| character(state)) - /// .and_then(|state| state.tag_node(std::borrow::Cow::Borrowed("c"))) + /// .and_then(|state| state.tag_node("c")) /// .and_then(|state| character(state)) /// }) /// } @@ -407,7 +407,7 @@ impl<'i, R: RuleType> ParserState<'i, R> { /// assert_eq!(find[0].as_str(), "c") /// ``` #[inline] - pub fn tag_node(mut self: Box, tag: Cow<'i, str>) -> ParseResult> { + pub fn tag_node(mut self: Box, tag: &'i str) -> ParseResult> { if let Some(QueueableToken::End { tag: old, .. }) = self.queue.last_mut() { *old = Some(tag) } diff --git a/vm/src/lib.rs b/vm/src/lib.rs index dddf07a2..6a944abf 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -245,7 +245,7 @@ impl Vm { #[cfg(feature = "grammar-extras")] OptimizedExpr::NodeTag(ref expr, ref tag) => self .parse_expr(expr, state) - .and_then(|state| state.tag_node(std::borrow::Cow::Owned(tag.clone()))), + .and_then(|state| state.tag_node(tag)), OptimizedExpr::RestoreOnErr(ref expr) => { state.restore_on_err(|state| self.parse_expr(expr, state)) } From 39adc10826a8d76f083022d739b884f72e117c51 Mon Sep 17 00:00:00 2001 From: sssooonnnggg Date: Thu, 4 Jan 2024 19:08:16 +0800 Subject: [PATCH 2/2] fix: fixed lifetime issue when processing tags --- vm/src/lib.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/vm/src/lib.rs b/vm/src/lib.rs index 6a944abf..c3e61d77 100644 --- a/vm/src/lib.rs +++ b/vm/src/lib.rs @@ -64,20 +64,20 @@ impl Vm { /// Runs a parser rule on an input #[allow(clippy::perf)] - pub fn parse<'a, 'i>( + pub fn parse<'a>( &'a self, rule: &'a str, - input: &'i str, - ) -> Result, Error<&str>> { + input: &'a str, + ) -> Result, Error<&str>> { pest::state(input, |state| self.parse_rule(rule, state)) } #[allow(clippy::suspicious)] - fn parse_rule<'a, 'i>( + fn parse_rule<'a>( &'a self, rule: &'a str, - state: Box>, - ) -> ParseResult>> { + state: Box>, + ) -> ParseResult>> { if let Some(ref listener) = self.listener { if listener(rule.to_owned(), state.position()) { return Err(ParserState::new(state.position().line_of())); @@ -179,11 +179,11 @@ impl Vm { } } - fn parse_expr<'a, 'i>( + fn parse_expr<'a>( &'a self, expr: &'a OptimizedExpr, - state: Box>, - ) -> ParseResult>> { + state: Box>, + ) -> ParseResult>> { match *expr { OptimizedExpr::Str(ref string) => state.match_string(string), OptimizedExpr::Insens(ref string) => state.match_insensitive(string), @@ -252,10 +252,10 @@ impl Vm { } } - fn skip<'a, 'i>( + fn skip<'a>( &'a self, - state: Box>, - ) -> ParseResult>> { + state: Box>, + ) -> ParseResult>> { match ( self.rules.contains_key("WHITESPACE"), self.rules.contains_key("COMMENT"),