Skip to content

Commit

Permalink
Merge pull request #251 from epage/perf
Browse files Browse the repository at this point in the history
perf(parser): Restore pre-consolidation performance
  • Loading branch information
epage committed Jun 14, 2023
2 parents f63c515 + be5234c commit ece4139
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 7 deletions.
10 changes: 10 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use crate::stream::{AsChar, Compare, Location, Offset, ParseSlice, Stream, Strea
/// - `&[u8]` and `&str`, see [`winnow::token::tag`][crate::token::tag]
pub trait Parser<I, O, E> {
/// Parse all of `input`, generating `O` from it
#[inline]
fn parse(&mut self, input: I) -> Result<O, E>
where
I: Stream,
Expand Down Expand Up @@ -614,6 +615,7 @@ impl<'a, I, O, E, F> Parser<I, O, E> for F
where
F: FnMut(I) -> IResult<I, O, E> + 'a,
{
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, O, E> {
self(i)
}
Expand All @@ -640,6 +642,7 @@ where
I: Stream<Token = u8>,
E: ParseError<I>,
{
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, u8, E> {
crate::token::one_of(*self).parse_next(i)
}
Expand Down Expand Up @@ -667,6 +670,7 @@ where
<I as Stream>::Token: AsChar + Copy,
E: ParseError<I>,
{
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Token, E> {
crate::token::one_of(*self).parse_next(i)
}
Expand Down Expand Up @@ -695,6 +699,7 @@ where
I: Compare<&'s [u8]> + StreamIsPartial,
I: Stream,
{
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> {
crate::token::tag(*self).parse_next(i)
}
Expand Down Expand Up @@ -723,6 +728,7 @@ where
I: Compare<&'s [u8; N]> + StreamIsPartial,
I: Stream,
{
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> {
crate::token::tag(*self).parse_next(i)
}
Expand Down Expand Up @@ -751,12 +757,14 @@ where
I: Compare<&'s str> + StreamIsPartial,
I: Stream,
{
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> {
crate::token::tag(*self).parse_next(i)
}
}

impl<I, E: ParseError<I>> Parser<I, (), E> for () {
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, (), E> {
Ok((i, ()))
}
Expand All @@ -769,6 +777,7 @@ macro_rules! impl_parser_for_tuple {
where
$($parser: Parser<I, $output, E>),+
{
#[inline(always)]
fn parse_next(&mut self, i: I) -> IResult<I, ($($output),+,), E> {
let ($(ref mut $parser),+,) = *self;

Expand Down Expand Up @@ -822,6 +831,7 @@ use alloc::boxed::Box;

#[cfg(feature = "alloc")]
impl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> {
#[inline(always)]
fn parse_next(&mut self, input: I) -> IResult<I, O, E> {
(**self).parse_next(input)
}
Expand Down
6 changes: 6 additions & 0 deletions src/stream/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1762,10 +1762,12 @@ impl Range {
}

impl crate::lib::std::ops::RangeBounds<usize> for Range {
#[inline(always)]
fn start_bound(&self) -> crate::lib::std::ops::Bound<&usize> {
crate::lib::std::ops::Bound::Included(&self.start_inclusive)
}

#[inline(always)]
fn end_bound(&self) -> crate::lib::std::ops::Bound<&usize> {
if let Some(end_inclusive) = &self.end_inclusive {
crate::lib::std::ops::Bound::Included(end_inclusive)
Expand Down Expand Up @@ -2118,6 +2120,7 @@ impl AsChar for u8 {
fn is_space(self) -> bool {
self == b' ' || self == b'\t'
}
#[inline]
fn is_newline(self) -> bool {
self == b'\n'
}
Expand Down Expand Up @@ -2155,6 +2158,7 @@ impl<'a> AsChar for &'a u8 {
fn is_space(self) -> bool {
*self == b' ' || *self == b'\t'
}
#[inline]
fn is_newline(self) -> bool {
*self == b'\n'
}
Expand Down Expand Up @@ -2193,6 +2197,7 @@ impl AsChar for char {
fn is_space(self) -> bool {
self == ' ' || self == '\t'
}
#[inline]
fn is_newline(self) -> bool {
self == '\n'
}
Expand Down Expand Up @@ -2231,6 +2236,7 @@ impl<'a> AsChar for &'a char {
fn is_space(self) -> bool {
*self == ' ' || *self == '\t'
}
#[inline]
fn is_newline(self) -> bool {
*self == '\n'
}
Expand Down
46 changes: 39 additions & 7 deletions src/token/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -497,18 +497,17 @@ where
trace("take_while", move |i: I| {
match (start_inclusive, end_inclusive) {
(0, None) => {
if <I as StreamIsPartial>::is_partial_supported() && i.is_partial() {
split_at_offset_partial(&i, |c| !list.contains_token(c))
if <I as StreamIsPartial>::is_partial_supported() {
take_while0_::<_, _, _, true>(i, &list)
} else {
split_at_offset_complete(&i, |c| !list.contains_token(c))
take_while0_::<_, _, _, false>(i, &list)
}
}
(1, None) => {
let e: ErrorKind = ErrorKind::Slice;
if <I as StreamIsPartial>::is_partial_supported() && i.is_partial() {
split_at_offset1_partial(&i, |c| !list.contains_token(c), e)
if <I as StreamIsPartial>::is_partial_supported() {
take_while1_::<_, _, _, true>(i, &list)
} else {
split_at_offset1_complete(&i, |c| !list.contains_token(c), e)
take_while1_::<_, _, _, false>(i, &list)
}
}
(start, end) => {
Expand Down Expand Up @@ -551,6 +550,39 @@ where
take_while(1.., list)
}

fn take_while0_<T, I, Error: ParseError<I>, const PARTIAL: bool>(
input: I,
list: &T,
) -> IResult<I, <I as Stream>::Slice, Error>
where
I: StreamIsPartial,
I: Stream,
T: ContainsToken<<I as Stream>::Token>,
{
if PARTIAL && input.is_partial() {
split_at_offset_partial(&input, |c| !list.contains_token(c))
} else {
split_at_offset_complete(&input, |c| !list.contains_token(c))
}
}

fn take_while1_<T, I, Error: ParseError<I>, const PARTIAL: bool>(
input: I,
list: &T,
) -> IResult<I, <I as Stream>::Slice, Error>
where
I: StreamIsPartial,
I: Stream,
T: ContainsToken<<I as Stream>::Token>,
{
let e: ErrorKind = ErrorKind::Slice;
if PARTIAL && input.is_partial() {
split_at_offset1_partial(&input, |c| !list.contains_token(c), e)
} else {
split_at_offset1_complete(&input, |c| !list.contains_token(c), e)
}
}

fn take_while_m_n_<T, I, Error: ParseError<I>, const PARTIAL: bool>(
input: I,
m: usize,
Expand Down
1 change: 1 addition & 0 deletions src/trace/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ compile_error!("`debug` requires `std`");
/// ```
#[cfg_attr(not(feature = "debug"), allow(unused_variables))]
#[cfg_attr(not(feature = "debug"), allow(unused_mut))]
#[cfg_attr(not(feature = "debug"), inline(always))]
pub fn trace<I: Stream, O, E>(
name: impl crate::lib::std::fmt::Display,
mut parser: impl Parser<I, O, E>,
Expand Down

0 comments on commit ece4139

Please sign in to comment.