From 71a7d9a9d39cf02be07a106d554b42a131471f3d Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Tue, 28 Apr 2026 19:31:04 +0900 Subject: [PATCH] perf(bytestring): micro-improve performance against ASCII conv (#865) --- bytestring/CHANGES.md | 1 + bytestring/src/lib.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/bytestring/CHANGES.md b/bytestring/CHANGES.md index a06640be..4c7332df 100644 --- a/bytestring/CHANGES.md +++ b/bytestring/CHANGES.md @@ -4,6 +4,7 @@ - Minimum supported Rust version (MSRV) is now 1.88. - Improve `From for String` performance. +- Improve ASCII `TryFrom` conversions performance. ## 1.5.0 diff --git a/bytestring/src/lib.rs b/bytestring/src/lib.rs index e50a0477..27434c96 100644 --- a/bytestring/src/lib.rs +++ b/bytestring/src/lib.rs @@ -195,6 +195,10 @@ impl TryFrom<&[u8]> for ByteString { #[inline] fn try_from(value: &[u8]) -> Result { + if value.is_ascii() { + return Ok(ByteString(Bytes::copy_from_slice(value))); + } + let _ = str::from_utf8(value)?; Ok(ByteString(Bytes::copy_from_slice(value))) } @@ -205,6 +209,10 @@ impl TryFrom> for ByteString { #[inline] fn try_from(value: Vec) -> Result { + if value.is_ascii() { + return Ok(ByteString(Bytes::from(value))); + } + let buf = String::from_utf8(value).map_err(|err| err.utf8_error())?; Ok(ByteString(Bytes::from(buf))) } @@ -215,6 +223,10 @@ impl TryFrom for ByteString { #[inline] fn try_from(value: Bytes) -> Result { + if value.is_ascii() { + return Ok(ByteString(value)); + } + let _ = str::from_utf8(value.as_ref())?; Ok(ByteString(value)) } @@ -225,6 +237,10 @@ impl TryFrom for ByteString { #[inline] fn try_from(value: bytes::BytesMut) -> Result { + if value.is_ascii() { + return Ok(ByteString(value.freeze())); + } + let _ = str::from_utf8(&value)?; Ok(ByteString(value.freeze())) } @@ -413,7 +429,10 @@ mod test { #[test] fn try_from_slice() { + let heart = "\u{1f496}"; let _ = ByteString::try_from(b"nice bytes").unwrap(); + assert_eq!(ByteString::try_from(heart.as_bytes()).unwrap(), heart); + ByteString::try_from(&[0, 159, 146, 150][..]).unwrap_err(); } #[test] @@ -432,12 +451,22 @@ mod test { #[test] fn try_from_bytes() { + let heart = "\u{1f496}"; let _ = ByteString::try_from(Bytes::from_static(b"nice bytes")).unwrap(); + assert_eq!( + ByteString::try_from(Bytes::from_static(heart.as_bytes())).unwrap(), + heart + ); } #[test] fn try_from_bytes_mut() { + let heart = "\u{1f496}"; let _ = ByteString::try_from(bytes::BytesMut::from(&b"nice bytes"[..])).unwrap(); + assert_eq!( + ByteString::try_from(bytes::BytesMut::from(heart.as_bytes())).unwrap(), + heart + ); } #[test]