From 7d550e3ebc5fc0e065517230360ac307f379c5c4 Mon Sep 17 00:00:00 2001 From: Orion Gonzalez Date: Tue, 31 Dec 2024 15:08:59 +0100 Subject: [PATCH] faster byte_serialized_unchanged --- form_urlencoded/src/lib.rs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/form_urlencoded/src/lib.rs b/form_urlencoded/src/lib.rs index 1d68579b7..e22aa1354 100644 --- a/form_urlencoded/src/lib.rs +++ b/form_urlencoded/src/lib.rs @@ -128,8 +128,24 @@ pub struct ByteSerialize<'a> { bytes: &'a [u8], } -fn byte_serialized_unchanged(byte: u8) -> bool { - matches!(byte, b'*' | b'-' | b'.' | b'0' ..= b'9' | b'A' ..= b'Z' | b'_' | b'a' ..= b'z') +/// This is a precomputed table of which chars match and which don't. +const MAGIC: u128 = const { + let mut magic = 0_u128; + let mut c = 0; + while c < 128 { + magic |= (matches!(c, b'*' | b'-' | b'.' | b'0' ..= b'9' | b'A' ..= b'Z' | b'_' | b'a' ..= b'z') + as u128) + << c; + c += 1; + } + magic +}; + +pub fn byte_serialized_unchanged(byte: u8) -> bool { + if byte > 128 { + return false; + } + ((MAGIC >> byte) & 1) == 1 } impl<'a> Iterator for ByteSerialize<'a> {