diff options
| author | Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> | 2022-05-29 19:21:57 +0200 |
|---|---|---|
| committer | Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> | 2022-05-31 10:51:35 +0200 |
| commit | 3358a41acbcb82daf3cd71197b2a053152a9a376 (patch) | |
| tree | 3eae0100aef267bc1f975ff3013e1d9c194ff119 | |
| parent | 9d1aeaeb827da7a10b7cfaccf0a1d6ebf414a7b5 (diff) | |
| download | rust-3358a41acbcb82daf3cd71197b2a053152a9a376.tar.gz rust-3358a41acbcb82daf3cd71197b2a053152a9a376.zip | |
Add unicode fast path to `is_printable`
Before, it would enter the full expensive check even for normal ascii characters. Now, it skips the check for the ascii characters in `32..127`. This range was checked manually from the current behavior.
| -rw-r--r-- | library/core/benches/fmt.rs | 11 | ||||
| -rwxr-xr-x | library/core/src/unicode/printable.py | 11 | ||||
| -rw-r--r-- | library/core/src/unicode/printable.rs | 11 |
3 files changed, 29 insertions, 4 deletions
diff --git a/library/core/benches/fmt.rs b/library/core/benches/fmt.rs index 9df66263459..ff726ff7559 100644 --- a/library/core/benches/fmt.rs +++ b/library/core/benches/fmt.rs @@ -110,6 +110,17 @@ fn write_str_macro_debug(bh: &mut Bencher) { } #[bench] +fn write_str_macro_debug_ascii(bh: &mut Bencher) { + bh.iter(|| { + let mut mem = String::new(); + let wr = &mut mem as &mut dyn fmt::Write; + for _ in 0..1000 { + write!(wr, "{:?}", "Hello, World!").unwrap(); + } + }); +} + +#[bench] fn write_u128_max(bh: &mut Bencher) { bh.iter(|| { test::black_box(format!("{}", u128::MAX)); diff --git a/library/core/src/unicode/printable.py b/library/core/src/unicode/printable.py index c42850d2324..7c37f5f099c 100755 --- a/library/core/src/unicode/printable.py +++ b/library/core/src/unicode/printable.py @@ -170,7 +170,7 @@ def main(): normal1 = compress_normal(normal1) print("""\ -// NOTE: The following code was generated by "src/libcore/unicode/printable.py", +// NOTE: The following code was generated by "library/core/src/unicode/printable.py", // do not edit directly! fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8], normal: &[u8]) -> bool { @@ -211,7 +211,14 @@ fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8], normal: & pub(crate) fn is_printable(x: char) -> bool { let x = x as u32; let lower = x as u16; - if x < 0x10000 { + + if x < 32 { + // ASCII fast path + false + } else if x < 127 { + // ASCII fast path + true + } else if x < 0x10000 { check(lower, SINGLETONS0U, SINGLETONS0L, NORMAL0) } else if x < 0x20000 { check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1) diff --git a/library/core/src/unicode/printable.rs b/library/core/src/unicode/printable.rs index 1502b3160bc..31cf88a4149 100644 --- a/library/core/src/unicode/printable.rs +++ b/library/core/src/unicode/printable.rs @@ -1,4 +1,4 @@ -// NOTE: The following code was generated by "src/libcore/unicode/printable.py", +// NOTE: The following code was generated by "library/core/src/unicode/printable.py", // do not edit directly! fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8], normal: &[u8]) -> bool { @@ -39,7 +39,14 @@ fn check(x: u16, singletonuppers: &[(u8, u8)], singletonlowers: &[u8], normal: & pub(crate) fn is_printable(x: char) -> bool { let x = x as u32; let lower = x as u16; - if x < 0x10000 { + + if x < 32 { + // ASCII fast path + false + } else if x < 127 { + // ASCII fast path + true + } else if x < 0x10000 { check(lower, SINGLETONS0U, SINGLETONS0L, NORMAL0) } else if x < 0x20000 { check(lower, SINGLETONS1U, SINGLETONS1L, NORMAL1) |
