diff options
| author | bors <bors@rust-lang.org> | 2021-05-20 00:55:27 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-20 00:55:27 +0000 |
| commit | a426fc37f2269093ef1a4dbb3e31b3247980fccc (patch) | |
| tree | 1eb155def582f17b39868872390c1206d5129785 /library/alloc/src | |
| parent | df70463ea5d701489d6f53dc780a2c16294d6143 (diff) | |
| parent | c7c93364697615edefccf281fa69b3f3af3dc67b (diff) | |
| download | rust-a426fc37f2269093ef1a4dbb3e31b3247980fccc.tar.gz rust-a426fc37f2269093ef1a4dbb3e31b3247980fccc.zip | |
Auto merge of #85391 - Mark-Simulacrum:opt-tostring, r=scottmcm
Avoid zero-length memcpy in formatting This has two separate and somewhat orthogonal commits. The first change adjusts the ToString general impl for all types that implement Display; it no longer uses the full format machinery, rather directly falling onto a `std::fmt::Display::fmt` call. The second change directly adjusts the general core::fmt::write function which handles the production of format_args! to avoid zero-length push_str calls. Both changes target the fact that push_str will still call memmove internally (or a similar function), as it doesn't know the length of the passed string. For zero-length strings in particular, this is quite expensive, and even for very short (several bytes long) strings, this is also expensive. Future work in this area may wish to have us fallback to write_char or similar, which may be cheaper on the (typically) short strings between the interpolated pieces in format_args!.
Diffstat (limited to 'library/alloc/src')
| -rw-r--r-- | library/alloc/src/string.rs | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index e6252452470..ec09595e357 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -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 } |
