Skip to content

Commit a66b596

Browse files
zakcutnermarmeladema
authored andcommitted
Extend tests and benchmarks completeness
1 parent 50303c4 commit a66b596

File tree

6 files changed

+378
-114
lines changed

6 files changed

+378
-114
lines changed

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,11 @@ memmem = "0.1"
1616
twoway = "0.2"
1717

1818
[[bench]]
19-
name = "avx2_anysize"
19+
name = "i386"
20+
harness = false
21+
22+
[[bench]]
23+
name = "random"
2024
harness = false
2125

2226
[profile.release]

benches/i386.rs

Lines changed: 291 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
use criterion::{black_box, criterion_group, criterion_main, Criterion};
2+
use memmem::{Searcher, TwoWaySearcher};
3+
use std::{
4+
fs::{self, File},
5+
io::{BufRead, BufReader},
6+
};
7+
use strstr::avx2::*;
8+
9+
fn search_short_haystack(c: &mut Criterion) {
10+
let mut needles = BufReader::new(File::open("data/words.txt").unwrap())
11+
.lines()
12+
.map(Result::unwrap)
13+
.filter(|needle| needle.len() > 1)
14+
.collect::<Vec<_>>();
15+
needles.sort_unstable_by_key(|needle| needle.len());
16+
let needles = needles.iter().map(String::as_str).collect::<Vec<_>>();
17+
18+
let mut group = c.benchmark_group("short_haystack");
19+
20+
group.bench_function("String::find", |b| {
21+
b.iter(|| {
22+
for (i, needle) in needles.iter().enumerate() {
23+
for haystack in &needles[i..] {
24+
black_box(haystack.find(needle));
25+
}
26+
}
27+
});
28+
});
29+
30+
group.bench_function("TwoWaySearcher::search_in", |b| {
31+
let searchers = needles
32+
.iter()
33+
.map(|needle| TwoWaySearcher::new(needle.as_bytes()))
34+
.collect::<Vec<_>>();
35+
36+
b.iter(|| {
37+
for (i, searcher) in searchers.iter().enumerate() {
38+
for haystack in &needles[i..] {
39+
black_box(searcher.search_in(haystack.as_bytes()));
40+
}
41+
}
42+
});
43+
});
44+
45+
group.bench_function("twoway::find_bytes", |b| {
46+
b.iter(|| {
47+
for (i, needle) in needles.iter().enumerate() {
48+
for haystack in &needles[i..] {
49+
black_box(twoway::find_bytes(haystack.as_bytes(), needle.as_bytes()));
50+
}
51+
}
52+
});
53+
});
54+
55+
group.bench_function("strstr_avx2_original", |b| {
56+
b.iter(|| {
57+
for (i, needle) in needles.iter().enumerate() {
58+
for haystack in &needles[i..] {
59+
black_box(unsafe {
60+
strstr_avx2_original(haystack.as_bytes(), needle.as_bytes())
61+
});
62+
}
63+
}
64+
});
65+
});
66+
67+
group.bench_function("strstr_avx2_rust_simple", |b| {
68+
b.iter(|| {
69+
for (i, needle) in needles.iter().enumerate() {
70+
for haystack in &needles[i..] {
71+
black_box(unsafe {
72+
strstr_avx2_rust_simple(haystack.as_bytes(), needle.as_bytes())
73+
});
74+
}
75+
}
76+
});
77+
});
78+
79+
group.bench_function("strstr_avx2_rust_simple_2", |b| {
80+
b.iter(|| {
81+
for (i, needle) in needles.iter().enumerate() {
82+
for haystack in &needles[i..] {
83+
black_box(unsafe {
84+
strstr_avx2_rust_simple_2(haystack.as_bytes(), needle.as_bytes())
85+
});
86+
}
87+
}
88+
});
89+
});
90+
91+
group.bench_function("strstr_avx2_rust_fast", |b| {
92+
b.iter(|| {
93+
for (i, needle) in needles.iter().enumerate() {
94+
for haystack in &needles[i..] {
95+
black_box(unsafe {
96+
strstr_avx2_rust_fast(haystack.as_bytes(), needle.as_bytes())
97+
});
98+
}
99+
}
100+
});
101+
});
102+
103+
group.bench_function("strstr_avx2_rust_fast_2", |b| {
104+
b.iter(|| {
105+
for (i, needle) in needles.iter().enumerate() {
106+
for haystack in &needles[i..] {
107+
black_box(strstr_avx2_rust_fast_2(
108+
haystack.as_bytes(),
109+
needle.as_bytes(),
110+
));
111+
}
112+
}
113+
});
114+
});
115+
116+
group.bench_function("strstr_avx2_rust_aligned", |b| {
117+
b.iter(|| {
118+
for (i, needle) in needles.iter().enumerate() {
119+
for haystack in &needles[i..] {
120+
black_box(unsafe {
121+
strstr_avx2_rust_aligned(haystack.as_bytes(), needle.as_bytes())
122+
});
123+
}
124+
}
125+
});
126+
});
127+
128+
group.bench_function("StrStrAVX2Searcher::search_in", |b| {
129+
let searchers = needles
130+
.iter()
131+
.map(|&needle| StrStrAVX2Searcher::new(needle.as_bytes()))
132+
.collect::<Vec<_>>();
133+
134+
b.iter(|| {
135+
for (i, searcher) in searchers.iter().enumerate() {
136+
for haystack in &needles[i..] {
137+
black_box(searcher.search_in(haystack.as_bytes()));
138+
}
139+
}
140+
});
141+
});
142+
143+
group.bench_function("DynamicAvx2Searcher::search_in", |b| {
144+
let searchers = needles
145+
.iter()
146+
.map(|&needle| {
147+
DynamicAvx2Searcher::new(needle.as_bytes().to_owned().into_boxed_slice())
148+
})
149+
.collect::<Vec<_>>();
150+
151+
b.iter(|| {
152+
for (i, searcher) in searchers.iter().enumerate() {
153+
for haystack in &needles[i..] {
154+
black_box(searcher.search_in(haystack.as_bytes()));
155+
}
156+
}
157+
});
158+
});
159+
160+
group.finish();
161+
}
162+
163+
fn search_long_haystack(c: &mut Criterion) {
164+
let haystack = fs::read("data/i386.txt").unwrap();
165+
let haystack = String::from_utf8_lossy(&haystack);
166+
167+
let needles = BufReader::new(File::open("data/words.txt").unwrap())
168+
.lines()
169+
.map(Result::unwrap)
170+
.filter(|needle| needle.len() > 1)
171+
.collect::<Vec<_>>();
172+
173+
let mut group = c.benchmark_group("long_haystack");
174+
175+
group.bench_function("String::find", |b| {
176+
b.iter(|| {
177+
for needle in &needles {
178+
black_box(haystack.find(needle));
179+
}
180+
});
181+
});
182+
183+
group.bench_function("TwoWaySearcher::search_in", |b| {
184+
let searchers = needles
185+
.iter()
186+
.map(|needle| TwoWaySearcher::new(needle.as_bytes()))
187+
.collect::<Vec<_>>();
188+
189+
b.iter(|| {
190+
for searcher in &searchers {
191+
black_box(searcher.search_in(haystack.as_bytes()));
192+
}
193+
});
194+
});
195+
196+
group.bench_function("twoway::find_bytes", |b| {
197+
b.iter(|| {
198+
for needle in &needles {
199+
black_box(twoway::find_bytes(haystack.as_bytes(), needle.as_bytes()));
200+
}
201+
});
202+
});
203+
204+
group.bench_function("strstr_avx2_original", |b| {
205+
b.iter(|| {
206+
for needle in &needles {
207+
black_box(unsafe { strstr_avx2_original(haystack.as_bytes(), needle.as_bytes()) });
208+
}
209+
});
210+
});
211+
212+
group.bench_function("strstr_avx2_rust_simple", |b| {
213+
b.iter(|| {
214+
for needle in &needles {
215+
black_box(unsafe {
216+
strstr_avx2_rust_simple(haystack.as_bytes(), needle.as_bytes())
217+
});
218+
}
219+
});
220+
});
221+
222+
group.bench_function("strstr_avx2_rust_simple_2", |b| {
223+
b.iter(|| {
224+
for needle in &needles {
225+
black_box(unsafe {
226+
strstr_avx2_rust_simple_2(haystack.as_bytes(), needle.as_bytes())
227+
});
228+
}
229+
});
230+
});
231+
232+
group.bench_function("strstr_avx2_rust_fast", |b| {
233+
b.iter(|| {
234+
for needle in &needles {
235+
black_box(unsafe { strstr_avx2_rust_fast(haystack.as_bytes(), needle.as_bytes()) });
236+
}
237+
});
238+
});
239+
240+
group.bench_function("strstr_avx2_rust_fast_2", |b| {
241+
b.iter(|| {
242+
for needle in &needles {
243+
black_box(strstr_avx2_rust_fast_2(
244+
haystack.as_bytes(),
245+
needle.as_bytes(),
246+
));
247+
}
248+
});
249+
});
250+
251+
group.bench_function("strstr_avx2_rust_aligned", |b| {
252+
b.iter(|| {
253+
for needle in &needles {
254+
black_box(unsafe {
255+
strstr_avx2_rust_aligned(haystack.as_bytes(), needle.as_bytes())
256+
});
257+
}
258+
});
259+
});
260+
261+
group.bench_function("StrStrAVX2Searcher::search_in", |b| {
262+
let searchers = needles
263+
.iter()
264+
.map(|needle| StrStrAVX2Searcher::new(needle.as_bytes()))
265+
.collect::<Vec<_>>();
266+
267+
b.iter(|| {
268+
for searcher in &searchers {
269+
black_box(searcher.search_in(haystack.as_bytes()));
270+
}
271+
});
272+
});
273+
274+
group.bench_function("DynamicAvx2Searcher::search_in", |b| {
275+
let searchers = needles
276+
.iter()
277+
.map(|needle| DynamicAvx2Searcher::new(needle.as_bytes().to_owned().into_boxed_slice()))
278+
.collect::<Vec<_>>();
279+
280+
b.iter(|| {
281+
for searcher in &searchers {
282+
black_box(searcher.search_in(haystack.as_bytes()));
283+
}
284+
});
285+
});
286+
287+
group.finish();
288+
}
289+
290+
criterion_group!(benches, search_short_haystack, search_long_haystack);
291+
criterion_main!(benches);

benches/avx2_anysize.rs renamed to benches/random.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
11
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
22
use memmem::{Searcher, TwoWaySearcher};
3-
use std::str;
43
use strstr::avx2::*;
54

6-
fn criterion_benchmark(c: &mut Criterion) {
7-
let haystack = include_bytes!("../data/haystack");
8-
let needle = include_bytes!("../data/needle");
5+
fn search(c: &mut Criterion) {
6+
let haystack = include_str!("../data/haystack");
7+
let needle = include_str!("../data/needle");
98

109
let sizes = [1, 5, 10, 20, 50, 100, 1000];
1110

1211
for (i, &size) in sizes.iter().enumerate() {
13-
let mut group = c.benchmark_group(format!("{}-byte needle", size));
12+
let mut group = c.benchmark_group(format!("needle_{}_bytes", size));
1413
let needle = &needle[..size];
1514

1615
for &size in &sizes[i..] {
17-
let parameter = &format!("{}-byte haystack", size);
16+
let parameter = &format!("haystack_{}_bytes", size);
1817
let haystack = &haystack[..size];
1918

2019
group.bench_with_input(
2120
BenchmarkId::new("String::find", parameter),
2221
&size,
2322
|b, _| {
24-
let haystack = str::from_utf8(haystack).unwrap();
25-
let needle = str::from_utf8(needle).unwrap();
2623
b.iter(|| haystack.find(needle));
2724
},
2825
);
2926

27+
let haystack = haystack.as_bytes();
28+
let needle = needle.as_bytes();
29+
3030
group.bench_with_input(
3131
BenchmarkId::new("TwoWaySearcher::search_in", parameter),
3232
&size,
@@ -115,5 +115,5 @@ fn criterion_benchmark(c: &mut Criterion) {
115115
}
116116
}
117117

118-
criterion_group!(benches, criterion_benchmark);
118+
criterion_group!(benches, search);
119119
criterion_main!(benches);
File renamed without changes.

0 commit comments

Comments
 (0)