provide EscapedStr type for faster string encoding

This commit is contained in:
Conrad Ludgate
2025-07-17 12:07:09 +01:00
parent b8435190d1
commit d6f4dc4949
4 changed files with 59 additions and 1 deletions

View File

@@ -18,6 +18,9 @@ struct Bar {
pub fn escape(c: &mut Criterion) {
c.bench_function("small", |b| bench_json_encode_inner(b, "object_key"));
c.bench_function("small_static", |b| {
bench_json_encode_inner(b, &json::EscapedStr::from_static("object_key"));
});
c.bench_function("large_fmt", |b| {
let value = Foo {
some_field: Bar {

View File

@@ -81,6 +81,7 @@ mod macros;
mod str;
mod value;
pub use str::EscapedStr;
pub use value::{KeyEncoder, Null, ValueEncoder};
#[must_use]

View File

@@ -8,10 +8,63 @@
//!
//! With modifications by Conrad Ludgate on behalf of Databricks.
use std::fmt::{self, Write};
use std::{
borrow::Cow,
fmt::{self, Write},
};
use crate::{KeyEncoder, ValueEncoder, ValueSer};
pub struct EscapedStr(Cow<'static, [u8]>);
impl EscapedStr {
/// Assumes the string does not need escaping.
///
/// # Panics
///
/// This will panic if the string does need escaping.
pub const fn from_static(s: &'static str) -> Self {
let bytes = s.as_bytes();
let mut i = 0;
while i < bytes.len() {
let byte = bytes[i];
let escape = ESCAPE[byte as usize];
assert!(escape == 0, "a character in the string needed escaping");
i += 1;
}
Self(Cow::Borrowed(bytes))
}
/// Escapes the string eagerly.
pub fn escape(s: &str) -> Self {
let mut writer = Vec::with_capacity(s.len());
Collect { buf: &mut writer }
.write_str(s)
.expect("formatting should not error");
Self(Cow::Owned(writer))
}
}
impl KeyEncoder for &EscapedStr {}
impl ValueEncoder for &EscapedStr {
fn encode(self, v: crate::ValueSer<'_>) {
let buf = &mut *v.buf;
buf.reserve(2 + self.0.len());
buf.push(b'"');
buf.extend_from_slice(&self.0);
buf.push(b'"');
v.finish();
}
}
impl KeyEncoder for &str {}
impl ValueEncoder for &str {
#[inline]

View File

@@ -84,6 +84,7 @@ impl<T: ValueEncoder> ValueEncoder for Option<T> {
}
/// Represents the JSON null value.
#[derive(Clone, Copy)]
pub struct Null;
impl ValueEncoder for Null {