Avoid checking long strings for matching against whitespace

Previously, the string was checked for starting with newlines and ending
with spaces, then ensuring that the length of those substrings were
short enough to use our constant. Instead, only do the check for as many
items as we have in the WS constant.

In the worst case, this avoids an O(n) check if the input is a long
string of `\n`, possibly followed by a long string of spaces.
This commit is contained in:
Zachary Dremann 2020-07-06 16:07:29 -04:00
parent 1235f1c11a
commit d97525eb5e

View File

@ -1,4 +1,10 @@
use std::{borrow::Borrow, cmp::Ordering, fmt, hash, iter, ops::Deref, sync::Arc};
use std::{
borrow::Borrow,
cmp::{self, Ordering},
fmt, hash, iter,
ops::Deref,
sync::Arc,
};
/// A `SmolStr` is a string type that has the following properties:
///
@ -358,10 +364,17 @@ impl Repr {
};
}
let newlines = text.bytes().take_while(|&b| b == b'\n').count();
if text[newlines..].bytes().all(|b| b == b' ') {
let spaces = len - newlines;
if newlines <= N_NEWLINES && spaces <= N_SPACES {
if len <= N_NEWLINES + N_SPACES {
let bytes = text.as_bytes();
let possible_newline_count = cmp::min(len, N_NEWLINES);
let newlines = bytes[..possible_newline_count]
.iter()
.take_while(|&&b| b == b'\n')
.count();
let possible_space_count = len - newlines;
if possible_space_count <= N_SPACES && bytes[newlines..].iter().all(|&b| b == b' ')
{
let spaces = possible_space_count;
return Repr::Substring { newlines, spaces };
}
}