diff --git a/library/core/src/str/pattern.rs b/library/core/src/str/pattern.rs index bcbbb11c83b2f..9bea4ca523b2a 100644 --- a/library/core/src/str/pattern.rs +++ b/library/core/src/str/pattern.rs @@ -429,8 +429,18 @@ unsafe impl<'a> Searcher<'a> for CharSearcher<'a> { SearchStep::Done } } - #[inline] + #[inline(always)] fn next_match(&mut self) -> Option<(usize, usize)> { + if self.utf8_size == 1 { + let find = |haystack: &[u8]| memchr::memchr(self.utf8_encoded[0], haystack); + return match find(self.haystack.as_bytes().get(self.finger..self.finger_back)?) { + Some(x) => { + self.finger += x + 1; + Some((self.finger - 1, self.finger)) + } + None => None, + }; + } loop { // get the haystack after the last character found let bytes = self.haystack.as_bytes().get(self.finger..self.finger_back)?; @@ -498,6 +508,16 @@ unsafe impl<'a> ReverseSearcher<'a> for CharSearcher<'a> { } #[inline] fn next_match_back(&mut self) -> Option<(usize, usize)> { + if self.utf8_size == 1 { + let find = |haystack: &[u8]| memchr::memrchr(self.utf8_encoded[0], haystack); + return match find(self.haystack.as_bytes().get(self.finger..self.finger_back)?) { + Some(x) => { + self.finger_back = self.finger + x; + Some((self.finger_back, self.finger_back + 1)) + } + None => None, + }; + } let haystack = self.haystack.as_bytes(); loop { // get the haystack up to but not including the last character searched diff --git a/library/coretests/benches/pattern.rs b/library/coretests/benches/pattern.rs index b0f8b39c22e16..259519c6633f1 100644 --- a/library/coretests/benches/pattern.rs +++ b/library/coretests/benches/pattern.rs @@ -39,3 +39,27 @@ fn ends_with_str(b: &mut Bencher) { } }) } + +#[bench] +fn splitn_on_http_response(b: &mut Bencher) { + fn parse_http(s: &str) -> Result<(&str, &str, &str), &str> { + let mut parts = s.splitn(3, ' '); + let version = parts.next().ok_or("No version")?; + let code = parts.next().ok_or("No status code")?; + let description = parts.next().ok_or("No description")?; + Ok((version, code, description)) + } + + let response = String::from("HTTP/1.1 418 I'm a teapot\r\n"); + let mut res: (&str, &str, &str) = ("", "", ""); + b.iter(|| { + for _ in 0..1024 { + res = black_box(match parse_http(black_box(&response)) { + Ok(data) => data, + Err(_) => { + continue; + } + }) + } + }) +}