From 32235db2a76f189f73063160d66b80034d8be62f Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Mon, 29 Feb 2016 16:32:29 +0100 Subject: [PATCH] fmt: Skip calling write_str for empty strings `format_args!` uses one string literal per used `{}`, in many cases, the separating string pieces are empty. For example, `write!(w, "{}", x);` will attempt to write one empty string before the `{}` format, and `write!(w, "{}{}{}", x, y, z);" will write three empty string pieces between formats. Simply skip writing if the string is empty. It is a cheap branch compared to the virtual Write::write_str call that it makes possible to skip. It does not solve issue #10761 in any way, yet that's where I noticed this. The testcase in the issue shows a performance difference between `write!(w, "abc")` and `write!(w, "{}", "abc")`, and this change halves the size of the difference. --- src/libcore/fmt/mod.rs | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs index a3b09e9db42d1..4e713826b6b2d 100644 --- a/src/libcore/fmt/mod.rs +++ b/src/libcore/fmt/mod.rs @@ -792,7 +792,9 @@ pub fn write(output: &mut Write, args: Arguments) -> Result { None => { // We can use default formatting parameters for all arguments. for (arg, piece) in args.args.iter().zip(pieces.by_ref()) { - try!(formatter.buf.write_str(*piece)); + if !piece.is_empty() { + try!(formatter.buf.write_str(*piece)); + } try!((arg.formatter)(arg.value, &mut formatter)); } } @@ -800,7 +802,9 @@ pub fn write(output: &mut Write, args: Arguments) -> Result { // Every spec has a corresponding argument that is preceded by // a string piece. for (arg, piece) in fmt.iter().zip(pieces.by_ref()) { - try!(formatter.buf.write_str(*piece)); + if !piece.is_empty() { + try!(formatter.buf.write_str(*piece)); + } try!(formatter.run(arg)); } } @@ -809,7 +813,9 @@ pub fn write(output: &mut Write, args: Arguments) -> Result { // There can be only one trailing string piece left. match pieces.next() { Some(piece) => { - try!(formatter.buf.write_str(*piece)); + if !piece.is_empty() { + try!(formatter.buf.write_str(*piece)); + } } None => {} }