From 3358a41acbcb82daf3cd71197b2a053152a9a376 Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Sun, 29 May 2022 19:21:57 +0200 Subject: [PATCH] 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. --- library/core/benches/fmt.rs | 11 +++++++++++ library/core/src/unicode/printable.py | 11 +++++++++-- 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 9df66263459b1..ff726ff7559d8 100644 --- a/library/core/benches/fmt.rs +++ b/library/core/benches/fmt.rs @@ -109,6 +109,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(|| { diff --git a/library/core/src/unicode/printable.py b/library/core/src/unicode/printable.py index c42850d232413..7c37f5f099c7f 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 @@ def main(): 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 1502b3160bc22..31cf88a41497e 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)