Skip to content

Commit 2b0fd41

Browse files
committed
add benchmark functions
1 parent 6c8dc46 commit 2b0fd41

File tree

3 files changed

+168
-0
lines changed

3 files changed

+168
-0
lines changed

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![feature(test)]
2+
13
//! Utilities for validating string and char literals and turning them into
24
//! values they represent.
35
@@ -109,6 +111,7 @@ where
109111

110112
/// Used for mixed utf8 string literals, i.e. those that allow both unicode
111113
/// chars and high bytes.
114+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
112115
pub enum MixedUnit {
113116
/// Used for ASCII chars (written directly or via `\x00`..`\x7f` escapes)
114117
/// and Unicode chars (written directly or via `\u` escapes).

src/tests.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,3 +314,5 @@ fn test_unescape_raw_byte_str() {
314314
],
315315
);
316316
}
317+
318+
mod benches;

src/tests/benches.rs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
extern crate test;
2+
3+
use super::*;
4+
use std::iter::{once, repeat_n};
5+
6+
const LEN: usize = 10_000;
7+
8+
#[bench]
9+
fn bench_skip_ascii_whitespace(b: &mut test::Bencher) {
10+
let input: String = test::black_box(repeat_n('\n', LEN - 1).chain(once(' ')).collect());
11+
assert_eq!(input.len(), LEN);
12+
assert!(input.contains('\n'));
13+
b.iter(|| {
14+
let mut output = vec![];
15+
skip_ascii_whitespace(&mut input.chars(), 0, &mut |range, res| {
16+
output.push((range, res))
17+
});
18+
assert_eq!(
19+
output,
20+
[((0..LEN + 1), EscapeError::MultipleSkippedLinesWarning)]
21+
);
22+
});
23+
}
24+
25+
//
26+
// Check raw
27+
//
28+
29+
fn bench_check_raw(b: &mut test::Bencher, c: char, mode: Mode) {
30+
let input: String = test::black_box(repeat_n(c, LEN).collect());
31+
assert_eq!(input.len(), LEN * c.len_utf8());
32+
b.iter(|| {
33+
let mut output = vec![];
34+
unescape_unicode(&input, mode, &mut |range, res| output.push((range, res)));
35+
assert_eq!(output.len(), LEN);
36+
assert_eq!(output[0], ((0..c.len_utf8()), Ok(c)));
37+
});
38+
}
39+
40+
// raw str
41+
42+
#[bench]
43+
fn bench_check_raw_str_ascii(b: &mut test::Bencher) {
44+
bench_check_raw(b, 'a', Mode::RawStr);
45+
}
46+
47+
#[bench]
48+
fn bench_check_raw_str_unicode(b: &mut test::Bencher) {
49+
bench_check_raw(b, '🦀', Mode::RawStr);
50+
}
51+
52+
// raw byte str
53+
54+
#[bench]
55+
fn bench_check_raw_byte_str(b: &mut test::Bencher) {
56+
bench_check_raw(b, 'a', Mode::RawByteStr);
57+
}
58+
59+
// raw C str
60+
61+
#[bench]
62+
fn bench_check_raw_c_str_ascii(b: &mut test::Bencher) {
63+
bench_check_raw(b, 'a', Mode::RawCStr);
64+
}
65+
66+
#[bench]
67+
fn bench_check_raw_c_str_unicode(b: &mut test::Bencher) {
68+
bench_check_raw(b, '🦀', Mode::RawCStr);
69+
}
70+
71+
//
72+
// Unescape
73+
//
74+
75+
fn bench_unescape(b: &mut test::Bencher, s: &str, mode: Mode, expected: char) {
76+
let input: String = test::black_box(repeat_n(s, LEN).collect());
77+
assert_eq!(input.len(), LEN * s.len());
78+
b.iter(|| {
79+
let mut output = vec![];
80+
unescape_unicode(&input, mode, &mut |range, res| output.push((range, res)));
81+
assert_eq!(output.len(), LEN);
82+
assert_eq!(output[0], ((0..s.len()), Ok(expected)));
83+
});
84+
}
85+
86+
// str
87+
88+
#[bench]
89+
fn bench_unescape_str_trivial(b: &mut test::Bencher) {
90+
bench_unescape(b, r"a", Mode::Str, 'a');
91+
}
92+
93+
#[bench]
94+
fn bench_unescape_str_ascii(b: &mut test::Bencher) {
95+
bench_unescape(b, r"\n", Mode::Str, '\n');
96+
}
97+
98+
#[bench]
99+
fn bench_unescape_str_hex(b: &mut test::Bencher) {
100+
bench_unescape(b, r"\x22", Mode::Str, '"');
101+
}
102+
103+
#[bench]
104+
fn bench_unescape_str_unicode(b: &mut test::Bencher) {
105+
bench_unescape(b, r"\u{1f980}", Mode::Str, '🦀');
106+
}
107+
108+
// byte str
109+
110+
#[bench]
111+
fn bench_unescape_byte_str_trivial(b: &mut test::Bencher) {
112+
bench_unescape(b, r"a", Mode::ByteStr, 'a');
113+
}
114+
115+
#[bench]
116+
fn bench_unescape_byte_str_ascii(b: &mut test::Bencher) {
117+
bench_unescape(b, r"\n", Mode::ByteStr, b'\n' as char);
118+
}
119+
120+
#[bench]
121+
fn bench_unescape_byte_str_hex(b: &mut test::Bencher) {
122+
bench_unescape(b, r"\xff", Mode::ByteStr, b'\xff' as char);
123+
}
124+
125+
// C str
126+
127+
fn bench_unescape_c_str(b: &mut test::Bencher, s: &str, expected: MixedUnit) {
128+
let input: String = test::black_box(repeat_n(s, LEN).collect());
129+
assert_eq!(input.len(), LEN * s.len());
130+
b.iter(|| {
131+
let mut output = vec![];
132+
unescape_mixed(&input, Mode::CStr, &mut |range, res| {
133+
output.push((range, res))
134+
});
135+
assert_eq!(output.len(), LEN);
136+
assert_eq!(output[0], ((0..s.len()), Ok(expected)));
137+
});
138+
}
139+
140+
#[bench]
141+
fn bench_unescape_c_str_trivial(b: &mut test::Bencher) {
142+
bench_unescape_c_str(b, r"a", MixedUnit::Char('a'));
143+
}
144+
145+
#[bench]
146+
fn bench_unescape_c_str_ascii(b: &mut test::Bencher) {
147+
bench_unescape_c_str(b, r"\n", MixedUnit::Char('\n'));
148+
}
149+
150+
#[bench]
151+
fn bench_unescape_c_str_hex_ascii(b: &mut test::Bencher) {
152+
bench_unescape_c_str(b, r"\x22", MixedUnit::Char('"'));
153+
}
154+
155+
#[bench]
156+
fn bench_unescape_c_str_hex_byte(b: &mut test::Bencher) {
157+
bench_unescape_c_str(b, r"\xff", MixedUnit::HighByte(b'\xff'));
158+
}
159+
160+
#[bench]
161+
fn bench_unescape_c_str_unicode(b: &mut test::Bencher) {
162+
bench_unescape_c_str(b, r"\u{1f980}", MixedUnit::Char('🦀'));
163+
}

0 commit comments

Comments
 (0)