Skip to content

Commit c45c254

Browse files
committed
Add benchmarks for impl Debug for str
In order to inform future perf improvements and prevent regressions, lets add some benchmarks that stress `impl Debug for str`.
1 parent ddf4a17 commit c45c254

File tree

2 files changed

+80
-0
lines changed

2 files changed

+80
-0
lines changed

Diff for: core/benches/str.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use test::{black_box, Bencher};
33

44
mod char_count;
55
mod corpora;
6+
mod debug;
67
mod iter;
78

89
#[bench]

Diff for: core/benches/str/debug.rs

+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
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

Comments
 (0)