From 12ceb375fcebc887cc22866dfa3e676410a5e674 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Wed, 6 Sep 2023 13:53:19 +0200 Subject: [PATCH 1/2] parser: Use a lookup table for Delimiter::from_byte. It's faster. --- src/parser.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index 9c91f523..f91e3954 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -314,15 +314,21 @@ impl Delimiters { #[inline] fn from_byte(byte: Option) -> Delimiters { + const TABLE: [Delimiters; 256] = { + let mut table = [Delimiter::None; 256]; + table[b';' as usize] = Delimiter::Semicolon; + table[b'!' as usize] = Delimiter::Bang; + table[b',' as usize] = Delimiter::Comma; + table[b'{' as usize] = Delimiter::CurlyBracketBlock; + table[b'}' as usize] = ClosingDelimiter::CloseCurlyBracket; + table[b']' as usize] = ClosingDelimiter::CloseSquareBracket; + table[b')' as usize] = ClosingDelimiter::CloseParenthesis; + table + }; + match byte { - Some(b';') => Delimiter::Semicolon, - Some(b'!') => Delimiter::Bang, - Some(b',') => Delimiter::Comma, - Some(b'{') => Delimiter::CurlyBracketBlock, - Some(b'}') => ClosingDelimiter::CloseCurlyBracket, - Some(b']') => ClosingDelimiter::CloseSquareBracket, - Some(b')') => ClosingDelimiter::CloseParenthesis, - _ => Delimiter::None, + None => Delimiter::None, + Some(b) => TABLE[b as usize], } } } From adf08ea0b971c635195b743f8158b669b717eb0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Sun, 10 Sep 2023 17:48:40 +0200 Subject: [PATCH 2/2] tests: Add a benchmark for Delimiters::from_byte --- src/parser.rs | 2 +- src/tests.rs | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/parser.rs b/src/parser.rs index f91e3954..3b86447f 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -313,7 +313,7 @@ impl Delimiters { } #[inline] - fn from_byte(byte: Option) -> Delimiters { + pub(crate) fn from_byte(byte: Option) -> Delimiters { const TABLE: [Delimiters; 256] = { let mut table = [Delimiter::None; 256]; table[b';' as usize] = Delimiter::Semicolon; diff --git a/src/tests.rs b/src/tests.rs index 8dbee8a7..ae17bd81 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -9,7 +9,7 @@ use encoding_rs; use serde_json::{self, json, Map, Value}; use crate::color::{parse_color_with, FromParsedColor}; -use crate::{ColorParser, PredefinedColorSpace}; +use crate::{ColorParser, PredefinedColorSpace, Delimiters}; #[cfg(feature = "bench")] use self::test::Bencher; @@ -922,6 +922,18 @@ impl<'a> ToJson for CowRcStr<'a> { } } +#[bench] +#[cfg(feature = "bench")] +fn delimiter_from_byte(b: &mut Bencher) { + b.iter(|| { + for _ in 0..1000 { + for i in 0..256 { + std::hint::black_box(Delimiters::from_byte(Some(i as u8))); + } + } + }) +} + #[cfg(feature = "bench")] const BACKGROUND_IMAGE: &'static str = include_str!("big-data-url.css");