-
Hi, I switch a manual parsing code to winnow here and benchmarks say that it's now 30% slower. I was hoping for the opposite. :) Pasting the relevant code here: fn validate(path: &[u8]) -> Result<()> {
use winnow::{
ascii::alphanumeric1,
combinator::{alt, repeat},
error::InputError,
Parser,
};
// Rules
//
// * At least 1 character.
// * First character must be `/`
// * No trailing `/`
// * No `//`
// * Only ASCII alphanumeric, `_` or '/'
let allowed_chars = alt((
alphanumeric1::<&[u8], InputError<_>>.map(|_| ()),
b'_'.map(|_| ()),
));
let component = (b'/', repeat(1.., allowed_chars).map(|()| ()));
let non_root = repeat(1.., component).map(|()| ());
let root = b'/'.map(|_: u8| ());
alt((non_root, root)).parse(path).map_err(|_| {
Error::IncorrectType
})
} I already checked if just reducing to |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 14 replies
-
@epage Do you have a clue what could be the culprit here? :) |
Beta Was this translation helpful? Give feedback.
-
I winnow'ified another parser in zbus project, and this one regresses by 20%, even though I'm not using fn validate(name: &str) -> Result<()> {
use winnow::{
combinator::separated,
error::InputError,
stream::AsChar,
token::{one_of, take_while},
Parser,
};
// Rules
//
// * Only ASCII alphanumeric, `_` or '-'.
// * Must not begin with a `.`.
// * Must contain at least one `.`.
// * Each element must:
// * not begin with a digit.
// * be 1 character (so name must be minimum 3 characters long).
// * <= 255 characters.
if name.len() > 255 {
return Err(Error::InvalidWellKnownName(format!(
"`{}` is {} characters long, which is longer than maximum allowed (255)",
name,
name.len(),
)));
}
let first_element_char = one_of((AsChar::is_alpha, '_', '-'));
let subsequent_element_chars =
take_while::<_, _, InputError<_>>(0.., (AsChar::is_alphanum, '_', '-'));
let element = (first_element_char, subsequent_element_chars);
let mut well_known_name = separated(2.., element, '.');
well_known_name
.parse(name)
.map_err(|e| Error::InvalidWellKnownName(format!("{e}")))
} I tried replacing |
Beta Was this translation helpful? Give feedback.
I suspect the
alt
s are the biggest problem. Next, I would try to minimuze the use ofrepeat
.Something like
Hmm, was hoping to get rid of that last
alt
but I think switching totake_while
will make a big difference.