Improve speed of fmt::Debug for str and char

fixes #26920
This commit is contained in:
Simon Mazur 2015-09-24 02:03:47 +03:00
parent 5ca60d9431
commit 24b5d3afd7
2 changed files with 25 additions and 7 deletions

View file

@ -147,6 +147,7 @@ pub trait CharExt {
fn to_digit(self, radix: u32) -> Option<u32>;
fn escape_unicode(self) -> EscapeUnicode;
fn escape_default(self) -> EscapeDefault;
fn needs_escape_default(self) -> bool;
fn len_utf8(self) -> usize;
fn len_utf16(self) -> usize;
fn encode_utf8(self, dst: &mut [u8]) -> Option<usize>;
@ -194,6 +195,15 @@ impl CharExt for char {
EscapeDefault { state: init_state }
}
#[inline]
fn needs_escape_default(self) -> bool {
match self {
'\\' | '\'' | '"' => true,
'\x20' ... '\x7e' => false,
_ => true
}
}
#[inline]
fn len_utf8(self) -> usize {
let code = self as u32;

View file

@ -1310,11 +1310,20 @@ impl Display for bool {
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for str {
fn fmt(&self, f: &mut Formatter) -> Result {
try!(write!(f, "\""));
for c in self.chars().flat_map(|c| c.escape_default()) {
try!(f.write_char(c))
try!(f.write_char('"'));
let mut from = 0;
for (i, c) in self.char_indices() {
// If char needs escaping, flush backlog so far and write, else skip
if c.needs_escape_default() {
try!(f.write_str(&self[from..i]));
for e in c.escape_default() {
try!(f.write_char(e));
}
from = i + c.len_utf8();
}
}
write!(f, "\"")
try!(f.write_str(&self[from..]));
f.write_char('"')
}
}
@ -1328,12 +1337,11 @@ impl Display for str {
#[stable(feature = "rust1", since = "1.0.0")]
impl Debug for char {
fn fmt(&self, f: &mut Formatter) -> Result {
use char::CharExt;
try!(write!(f, "'"));
try!(f.write_char('\''));
for c in self.escape_default() {
try!(f.write_char(c))
}
write!(f, "'")
f.write_char('\'')
}
}