Skip to content

Commit 7135c91

Browse files
authored
feat: Faster string serialization by escaping in byte space. (#30)
1 parent f32af37 commit 7135c91

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

questdb-rs/src/ingress/mod.rs

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -409,44 +409,56 @@ fn write_escaped_impl<Q, C>(
409409
output: &mut String,
410410
s: &str)
411411
where
412-
C: Fn(char) -> bool,
413-
Q: Fn(&mut String) -> ()
412+
C: Fn(u8) -> bool,
413+
Q: Fn(&mut Vec<u8>) -> ()
414414
{
415+
let output_vec = unsafe { output.as_mut_vec() };
415416
let mut to_escape = 0usize;
416-
for c in s.chars() {
417-
if check_escape_fn(c) {
417+
for b in s.bytes() {
418+
if check_escape_fn(b) {
418419
to_escape += 1;
419420
}
420421
}
421422

422-
quoting_fn(output);
423+
quoting_fn(output_vec);
423424

424425
if to_escape == 0 {
425-
output.push_str(s);
426+
// output.push_str(s);
427+
output_vec.extend_from_slice(s.as_bytes());
426428
}
427429
else {
428-
output.reserve(s.len() + to_escape);
429-
for c in s.chars() {
430-
if check_escape_fn(c) {
431-
output.push('\\');
430+
let additional = s.len() + to_escape;
431+
output_vec.reserve(additional);
432+
let mut index = output_vec.len();
433+
unsafe { output_vec.set_len(index + additional) };
434+
for b in s.bytes() {
435+
if check_escape_fn(b) {
436+
unsafe {
437+
*output_vec.get_unchecked_mut(index) = b'\\';
438+
}
439+
index += 1;
432440
}
433-
output.push(c);
441+
442+
unsafe {
443+
*output_vec.get_unchecked_mut(index) = b;
444+
}
445+
index += 1;
434446
}
435447
}
436448

437-
quoting_fn(output);
449+
quoting_fn(output_vec);
438450
}
439451

440-
fn must_escape_unquoted(c: char) -> bool {
452+
fn must_escape_unquoted(c: u8) -> bool {
441453
match c {
442-
' ' | ',' | '=' | '\n' | '\r' | '\\' => true,
454+
b' ' | b',' | b'=' | b'\n' | b'\r' | b'\\' => true,
443455
_ => false
444456
}
445457
}
446458

447-
fn must_escape_quoted(c: char) -> bool {
459+
fn must_escape_quoted(c: u8) -> bool {
448460
match c {
449-
'\n' | '\r' | '"' | '\\' => true,
461+
b'\n' | b'\r' | b'"' | b'\\' => true,
450462
_ => false
451463
}
452464
}
@@ -462,7 +474,7 @@ fn write_escaped_unquoted(output: &mut String, s: &str) {
462474
fn write_escaped_quoted(output: &mut String, s: &str) {
463475
write_escaped_impl(
464476
must_escape_quoted,
465-
|output| output.push('"'),
477+
|output| output.push(b'"'),
466478
output,
467479
s)
468480
}
@@ -724,6 +736,7 @@ impl Buffer {
724736
self.state = State::Init;
725737
}
726738

739+
#[inline(always)]
727740
fn check_state(&self, op: Op) -> Result<()> {
728741
if (self.state as isize & op as isize) > 0 {
729742
return Ok(());
@@ -736,6 +749,7 @@ impl Buffer {
736749
Err(error)
737750
}
738751

752+
#[inline(always)]
739753
fn validate_max_name_len(&self, name: &str) -> Result<()> {
740754
if name.len() > self.max_name_len {
741755
return Err(error::fmt!(

0 commit comments

Comments
 (0)