Skip to content

Commit 32235db

Browse files
committed
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 rust-lang#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.
1 parent 0913004 commit 32235db

File tree

1 file changed

+9
-3
lines changed

1 file changed

+9
-3
lines changed

src/libcore/fmt/mod.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -792,15 +792,19 @@ pub fn write(output: &mut Write, args: Arguments) -> Result {
792792
None => {
793793
// We can use default formatting parameters for all arguments.
794794
for (arg, piece) in args.args.iter().zip(pieces.by_ref()) {
795-
try!(formatter.buf.write_str(*piece));
795+
if !piece.is_empty() {
796+
try!(formatter.buf.write_str(*piece));
797+
}
796798
try!((arg.formatter)(arg.value, &mut formatter));
797799
}
798800
}
799801
Some(fmt) => {
800802
// Every spec has a corresponding argument that is preceded by
801803
// a string piece.
802804
for (arg, piece) in fmt.iter().zip(pieces.by_ref()) {
803-
try!(formatter.buf.write_str(*piece));
805+
if !piece.is_empty() {
806+
try!(formatter.buf.write_str(*piece));
807+
}
804808
try!(formatter.run(arg));
805809
}
806810
}
@@ -809,7 +813,9 @@ pub fn write(output: &mut Write, args: Arguments) -> Result {
809813
// There can be only one trailing string piece left.
810814
match pieces.next() {
811815
Some(piece) => {
812-
try!(formatter.buf.write_str(*piece));
816+
if !piece.is_empty() {
817+
try!(formatter.buf.write_str(*piece));
818+
}
813819
}
814820
None => {}
815821
}

0 commit comments

Comments
 (0)