Skip to content

Commit

Permalink
Optimize default ToString impl
Browse files Browse the repository at this point in the history
This avoids a zero-length write_str call, which boils down to a zero-length
memmove and ultimately costs quite a few instructions on some workloads.

This is approximately a 0.33% instruction count win on diesel-check.
  • Loading branch information
Mark-Simulacrum committed May 17, 2021
1 parent 2a245f4 commit 80ac15f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 11 deletions.
5 changes: 3 additions & 2 deletions library/alloc/src/string.rs
Expand Up @@ -2323,9 +2323,10 @@ impl<T: fmt::Display + ?Sized> ToString for T {
// to try to remove it.
#[inline]
default fn to_string(&self) -> String {
use fmt::Write;
let mut buf = String::new();
buf.write_fmt(format_args!("{}", self))
let mut formatter = core::fmt::Formatter::new(&mut buf);
// Bypass format_args!() to avoid write_str with zero-length strs
fmt::Display::fmt(self, &mut formatter)
.expect("a Display implementation returned an error unexpectedly");
buf
}
Expand Down
32 changes: 23 additions & 9 deletions library/core/src/fmt/mod.rs
Expand Up @@ -221,6 +221,28 @@ pub struct Formatter<'a> {
buf: &'a mut (dyn Write + 'a),
}

impl<'a> Formatter<'a> {
/// Creates a new formatter with default settings.
///
/// This can be used as a micro-optimization in cases where a full `Arguments`
/// structure (as created by `format_args!`) is not necessary; `Arguments`
/// is a little more expensive to use in simple formatting scenarios.
///
/// Currently not intended for use outside of the standard library.
#[unstable(feature = "fmt_internals", reason = "internal to standard library", issue = "none")]
#[doc(hidden)]
pub fn new(buf: &'a mut (dyn Write + 'a)) -> Formatter<'a> {
Formatter {
flags: 0,
fill: ' ',
align: rt::v1::Alignment::Unknown,
width: None,
precision: None,
buf,
}
}
}

// NB. Argument is essentially an optimized partially applied formatting function,
// equivalent to `exists T.(&T, fn(&T, &mut Formatter<'_>) -> Result`.

Expand Down Expand Up @@ -1075,15 +1097,7 @@ pub trait UpperExp {
/// [`write!`]: crate::write!
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write(output: &mut dyn Write, args: Arguments<'_>) -> Result {
let mut formatter = Formatter {
flags: 0,
width: None,
precision: None,
buf: output,
align: rt::v1::Alignment::Unknown,
fill: ' ',
};

let mut formatter = Formatter::new(output);
let mut idx = 0;

match args.fmt {
Expand Down

0 comments on commit 80ac15f

Please sign in to comment.