Skip to content

Commit a96dc7a

Browse files
committed
Optimize decode_path by skipping UTF-8 validation for map keys
- Replaces read_string with read_str_as_bytes in Decoder. - Updates decode_path to compare raw bytes for keys, avoiding expensive UTF-8 validation during map traversal. - Removes unused read_string method. - Benchmarks show ~10% performance improvement in decode_path lookups.
1 parent ffd065c commit a96dc7a

File tree

2 files changed

+14
-6
lines changed

2 files changed

+14
-6
lines changed

src/decoder.rs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -446,19 +446,26 @@ impl<'de> Decoder<'de> {
446446
}
447447
}
448448

449-
/// Reads a string directly, following pointers if needed.
450-
pub(crate) fn read_string(&mut self) -> DecodeResult<&'de str> {
449+
/// Reads a string's bytes directly, following pointers if needed.
450+
/// Does NOT validate UTF-8.
451+
pub(crate) fn read_str_as_bytes(&mut self) -> DecodeResult<&'de [u8]> {
451452
let (size, type_num) = self.size_and_type();
452453
if type_num == TYPE_POINTER {
453454
// Pointer
454455
let new_ptr = self.decode_pointer(size);
455456
let saved_ptr = self.current_ptr;
456457
self.current_ptr = new_ptr;
457-
let result = self.read_string();
458+
let result = self.read_str_as_bytes();
458459
self.current_ptr = saved_ptr;
459460
result
460461
} else if type_num == TYPE_STRING {
461-
self.decode_string(size)
462+
let new_offset = self.current_ptr + size;
463+
if new_offset > self.buf.len() {
464+
return Err(self.invalid_db_error("string length exceeds buffer"));
465+
}
466+
let bytes = &self.buf[self.current_ptr..new_offset];
467+
self.current_ptr = new_offset;
468+
Ok(bytes)
462469
} else {
463470
Err(self.invalid_db_error(&format!("expected string, got type {type_num}")))
464471
}

src/result.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,10 @@ impl<'a, S: AsRef<[u8]>> LookupResult<'a, S> {
252252
let size = decoder.consume_map_header().map_err(with_path)?;
253253

254254
let mut found = false;
255+
let key_bytes = key.as_bytes();
255256
for _ in 0..size {
256-
let k = decoder.read_string().map_err(with_path)?;
257-
if k == key {
257+
let k = decoder.read_str_as_bytes().map_err(with_path)?;
258+
if k == key_bytes {
258259
found = true;
259260
break;
260261
} else {

0 commit comments

Comments
 (0)