-
-
Save CAD97/2922d3132777310c1e22564f6c6dabdf to your computer and use it in GitHub Desktop.
Fix rust-lang/rust#10761 (2013) with a -1/+8 patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(unused_must_use)] | |
#![feature(test)] | |
extern crate test; | |
use std::fmt::{self, Write as FmtWrite}; | |
use std::io::{self, Write as IoWrite}; | |
use std::vec::Vec; | |
use test::Bencher; | |
struct FastWrite<W>(W); | |
impl<W: IoWrite> IoWrite for FastWrite<W> { | |
fn write(&mut self, buf: &[u8]) -> Result<usize, io::Error> { | |
self.0.write(buf) | |
} | |
fn flush(&mut self) -> Result<(), io::Error> { | |
self.0.flush() | |
} | |
fn write_vectored(&mut self, bufs: &[io::IoSlice<'_>]) -> io::Result<usize> { | |
self.0.write_vectored(bufs) | |
} | |
fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { | |
self.0.write_all(buf) | |
} | |
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> io::Result<()> { | |
if let Some(s) = fmt.as_str() { | |
self.0.write_all(s.as_bytes()) | |
} else { | |
self.0.write_fmt(fmt) | |
} | |
} | |
} | |
impl<W: FmtWrite> FmtWrite for FastWrite<W> { | |
fn write_str(&mut self, s: &str) -> fmt::Result { | |
self.0.write_str(s) | |
} | |
fn write_char(&mut self, c: char) -> fmt::Result { | |
self.0.write_char(c) | |
} | |
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result { | |
if let Some(s) = args.as_str() { | |
self.0.write_str(s) | |
} else { | |
self.0.write_fmt(args) | |
} | |
} | |
} | |
#[bench] | |
fn old_vec_write_value(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: Vec<u8> = Vec::new(); | |
for _ in 0..1000 { | |
mem.write("abc".as_bytes()); | |
} | |
}); | |
} | |
#[bench] | |
fn new_vec_write_value(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: FastWrite<Vec<u8>> = FastWrite(Vec::new()); | |
for _ in 0..1000 { | |
mem.write("abc".as_bytes()); | |
} | |
}); | |
} | |
#[bench] | |
fn old_vec_write_ref(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: Vec<u8> = Vec::new(); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
wr.write("abc".as_bytes()); | |
} | |
}); | |
} | |
#[bench] | |
fn new_vec_write_ref(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: FastWrite<Vec<u8>> = FastWrite(Vec::new()); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
wr.write("abc".as_bytes()); | |
} | |
}); | |
} | |
#[bench] | |
fn old_vec_write_macro1(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: Vec<u8> = Vec::new(); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
write!(wr, "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn new_vec_write_macro1(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: FastWrite<Vec<u8>> = FastWrite(Vec::new()); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
write!(wr, "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn old_vec_write_macro2(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: Vec<u8> = Vec::new(); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
write!(wr, "{}", "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn new_vec_write_macro2(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: FastWrite<Vec<u8>> = FastWrite(Vec::new()); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
write!(wr, "{}", "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn old_vec_write_fmt(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: Vec<u8> = Vec::new(); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
wr.write_fmt(format_args!("abc")); | |
} | |
}); | |
} | |
#[bench] | |
fn new_vec_write_fmt(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem: FastWrite<Vec<u8>> = FastWrite(Vec::new()); | |
let wr = &mut mem as &mut dyn IoWrite; | |
for _ in 0..1000 { | |
wr.write_fmt(format_args!("abc")); | |
} | |
}); | |
} | |
#[bench] | |
fn old_string_write_value(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = String::new(); | |
for _ in 0..1000 { | |
mem.write_str("abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn new_string_write_value(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = FastWrite(String::new()); | |
for _ in 0..1000 { | |
mem.write_str("abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn old_string_write_ref(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = String::new(); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
wr.write_str("abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn new_string_write_ref(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = FastWrite(String::new()); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
wr.write_str("abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn old_string_write_macro1(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = String::new(); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
write!(wr, "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn new_string_write_macro1(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = FastWrite(String::new()); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
write!(wr, "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn old_string_write_macro2(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = String::new(); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
write!(wr, "{}", "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn new_string_write_macro2(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = FastWrite(String::new()); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
write!(wr, "{}", "abc"); | |
} | |
}); | |
} | |
#[bench] | |
fn old_string_write_fmt(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = String::new(); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
wr.write_fmt(format_args!("abc")); | |
} | |
}); | |
} | |
#[bench] | |
fn new_string_write_fmt(bh: &mut Bencher) { | |
bh.iter(|| { | |
let mut mem = FastWrite(String::new()); | |
let wr = &mut mem as &mut dyn FmtWrite; | |
for _ in 0..1000 { | |
wr.write_fmt(format_args!("abc")); | |
} | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
running 8 tests | |
test new_string_write_macro1 ... bench: 1,875 ns/iter (+/- 228) | |
test new_string_write_macro2 ... bench: 13,594 ns/iter (+/- 999) | |
test new_vec_write_macro1 ... bench: 1,637 ns/iter (+/- 175) | |
test new_vec_write_macro2 ... bench: 13,808 ns/iter (+/- 1,320) | |
test old_string_write_macro1 ... bench: 10,080 ns/iter (+/- 1,618) | |
test old_string_write_macro2 ... bench: 13,880 ns/iter (+/- 1,327) | |
test old_vec_write_macro1 ... bench: 10,037 ns/iter (+/- 779) | |
test old_vec_write_macro2 ... bench: 14,783 ns/iter (+/- 1,280) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- old/src/std/io/mod.rs | |
+++ new/src/std/io/mod.rs | |
@@ -1650,8 +1650,12 @@ | |
#[stable(feature = "rust1", since = "1.0.0")] | |
fn write_fmt(&mut self, fmt: fmt::Arguments<'_>) -> Result<()> { | |
+ if let Some(s) = fmt.as_str() { | |
+ return self.write_all(s.as_bytes()); | |
+ } | |
+ | |
// Create a shim which translates a Write to a fmt::Write and saves | |
// off I/O errors. instead of discarding them | |
struct Adapter<'a, T: ?Sized + 'a> { | |
inner: &'a mut T, | |
error: Result<()>, | |
} | |
--- old/src/core/fmt/mod.rs | |
+++ new/src/core/fmt/mod.rs | |
@@ -186,4 +186,8 @@ | |
#[stable(feature = "rust1", since = "1.0.0")] | |
fn write_fmt(mut self: &mut Self, args: Arguments<'_>) -> Result { | |
+ if let Some(s) = args.as_str() { | |
+ self.write_str(s) | |
+ } else { | |
- write(&mut self, args) | |
+ write(&mut self, args) | |
+ } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment