| 
 | 1 | +//! This primarily benchmarks `impl Debug for str`,  | 
 | 2 | +//! and it also explicitly tests that we minimizes calls to the underlying `Write`r.  | 
 | 3 | +//! While that is an implementation detail and there are no guarantees about it,  | 
 | 4 | +//! we should still try to minimize those calls over time rather than regress them.  | 
 | 5 | +
  | 
 | 6 | +use std::fmt::{self, Write};  | 
 | 7 | +use test::{black_box, Bencher};  | 
 | 8 | + | 
 | 9 | +#[derive(Default)]  | 
 | 10 | +struct CountingWriter {  | 
 | 11 | +    buf: String,  | 
 | 12 | +    write_calls: usize,  | 
 | 13 | +}  | 
 | 14 | + | 
 | 15 | +impl Write for CountingWriter {  | 
 | 16 | +    fn write_str(&mut self, s: &str) -> fmt::Result {  | 
 | 17 | +        self.buf.push_str(s);  | 
 | 18 | +        self.write_calls += 1;  | 
 | 19 | +        Ok(())  | 
 | 20 | +    }  | 
 | 21 | +}  | 
 | 22 | + | 
 | 23 | +fn assert_fmt(s: &str, expected: &str, expected_write_calls: usize) {  | 
 | 24 | +    let mut w = CountingWriter::default();  | 
 | 25 | + | 
 | 26 | +    write!(&mut w, "{s:?}").unwrap();  | 
 | 27 | +    assert_eq!(s.len(), 64);  | 
 | 28 | +    assert_eq!(w.buf, expected);  | 
 | 29 | +    assert_eq!(w.write_calls, expected_write_calls);  | 
 | 30 | +}  | 
 | 31 | + | 
 | 32 | +#[bench]  | 
 | 33 | +fn ascii_only(b: &mut Bencher) {  | 
 | 34 | +    let s = "just a bit of ascii text that has no escapes. 64 bytes exactly!!";  | 
 | 35 | +    assert_fmt(s, r#""just a bit of ascii text that has no escapes. 64 bytes exactly!!""#, 3);  | 
 | 36 | +    b.iter(|| {  | 
 | 37 | +        black_box(format!("{:?}", black_box(s)));  | 
 | 38 | +    });  | 
 | 39 | +}  | 
 | 40 | + | 
 | 41 | +#[bench]  | 
 | 42 | +fn ascii_escapes(b: &mut Bencher) {  | 
 | 43 | +    let s = "some\tmore\tascii\ttext\nthis time with some \"escapes\", also 64 byte";  | 
 | 44 | +    assert_fmt(  | 
 | 45 | +        s,  | 
 | 46 | +        r#""some\tmore\tascii\ttext\nthis time with some \"escapes\", also 64 byte""#,  | 
 | 47 | +        21,  | 
 | 48 | +    );  | 
 | 49 | +    b.iter(|| {  | 
 | 50 | +        black_box(format!("{:?}", black_box(s)));  | 
 | 51 | +    });  | 
 | 52 | +}  | 
 | 53 | + | 
 | 54 | +#[bench]  | 
 | 55 | +fn some_unicode(b: &mut Bencher) {  | 
 | 56 | +    let s = "egy kis szöveg néhány unicode betűvel. legyen ez is 64 byte.";  | 
 | 57 | +    assert_fmt(s, r#""egy kis szöveg néhány unicode betűvel. legyen ez is 64 byte.""#, 3);  | 
 | 58 | +    b.iter(|| {  | 
 | 59 | +        black_box(format!("{:?}", black_box(s)));  | 
 | 60 | +    });  | 
 | 61 | +}  | 
 | 62 | + | 
 | 63 | +#[bench]  | 
 | 64 | +fn mostly_unicode(b: &mut Bencher) {  | 
 | 65 | +    let s = "предложение из кириллических букв.";  | 
 | 66 | +    assert_fmt(s, r#""предложение из кириллических букв.""#, 3);  | 
 | 67 | +    b.iter(|| {  | 
 | 68 | +        black_box(format!("{:?}", black_box(s)));  | 
 | 69 | +    });  | 
 | 70 | +}  | 
 | 71 | + | 
 | 72 | +#[bench]  | 
 | 73 | +fn mixed(b: &mut Bencher) {  | 
 | 74 | +    let s = "\"❤️\"\n\"hűha ez betű\"\n\"кириллических букв\".";  | 
 | 75 | +    assert_fmt(s, r#""\"❤\u{fe0f}\"\n\"hűha ez betű\"\n\"кириллических букв\".""#, 36);  | 
 | 76 | +    b.iter(|| {  | 
 | 77 | +        black_box(format!("{:?}", black_box(s)));  | 
 | 78 | +    });  | 
 | 79 | +}  | 
0 commit comments