Fix big performance issue in string serialization (#1848)

This commit is contained in:
Ophir LOJKINE 2025-05-13 17:36:27 +02:00 committed by GitHub
parent 6120bb59cc
commit 178a351812
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -456,30 +456,38 @@ impl fmt::Display for EscapeQuotedString<'_> {
// | `"A\"B\"A"` | default | `DoubleQuotedString(String::from("A\"B\"A"))` | `"A""B""A"` |
let quote = self.quote;
let mut previous_char = char::default();
let mut peekable_chars = self.string.chars().peekable();
while let Some(&ch) = peekable_chars.peek() {
let mut start_idx = 0;
let mut peekable_chars = self.string.char_indices().peekable();
while let Some(&(idx, ch)) = peekable_chars.peek() {
match ch {
char if char == quote => {
if previous_char == '\\' {
write!(f, "{char}")?;
// the quote is already escaped with a backslash, skip
peekable_chars.next();
continue;
}
peekable_chars.next();
if peekable_chars.peek().map(|c| *c == quote).unwrap_or(false) {
write!(f, "{char}{char}")?;
peekable_chars.next();
} else {
write!(f, "{char}{char}")?;
match peekable_chars.peek() {
Some((_, c)) if *c == quote => {
// the quote is already escaped with another quote, skip
peekable_chars.next();
}
_ => {
// The quote is not escaped.
// Including idx in the range, so the quote at idx will be printed twice:
// in this call to write_str() and in the next one.
f.write_str(&self.string[start_idx..=idx])?;
start_idx = idx;
}
}
}
_ => {
write!(f, "{ch}")?;
peekable_chars.next();
}
}
previous_char = ch;
}
f.write_str(&self.string[start_idx..])?;
Ok(())
}
}