1 // pest. The Elegant Parser
2 // Copyright (c) 2018 Dragoș Tiselice
3 //
4 // Licensed under the Apache License, Version 2.0
5 // <LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0> or the MIT
6 // license <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7 // option. All files in the project carrying such notice may not be copied,
8 // modified, or distributed except according to those terms.
9 
10 use criterion::{criterion_group, criterion_main, Criterion};
11 use pest::Stack;
12 
snapshot_push_restore<T: Clone>(elements: impl Iterator<Item = T> + Clone)13 fn snapshot_push_restore<T: Clone>(elements: impl Iterator<Item = T> + Clone) {
14     let mut stack = Stack::<T>::new();
15     for elem in elements {
16         stack.snapshot();
17         stack.push(elem.clone());
18         stack.restore();
19         stack.push(elem);
20     }
21 }
22 
snapshot_push_clear_snapshot<T: Clone>(elements: impl Iterator<Item = T> + Clone)23 fn snapshot_push_clear_snapshot<T: Clone>(elements: impl Iterator<Item = T> + Clone) {
24     let mut stack = Stack::<T>::new();
25     for elem in elements {
26         stack.snapshot();
27         stack.push(elem);
28         stack.clear_snapshot();
29     }
30 }
31 
snapshot_pop_restore<T: Clone>(elements: impl Iterator<Item = T>)32 fn snapshot_pop_restore<T: Clone>(elements: impl Iterator<Item = T>) {
33     let mut stack = Stack::<T>::new();
34     for elem in elements {
35         stack.push(elem);
36     }
37     while !stack.is_empty() {
38         stack.snapshot();
39         stack.pop();
40         stack.restore();
41         stack.pop();
42     }
43 }
44 
snapshot_pop_clear<T: Clone>(elements: impl Iterator<Item = T>)45 fn snapshot_pop_clear<T: Clone>(elements: impl Iterator<Item = T>) {
46     let mut stack = Stack::<T>::new();
47     for elem in elements {
48         stack.push(elem);
49     }
50     while !stack.is_empty() {
51         stack.snapshot();
52         stack.pop();
53         stack.clear_snapshot();
54     }
55 }
56 
benchmark(b: &mut Criterion)57 fn benchmark(b: &mut Criterion) {
58     use core::iter::repeat;
59     // use criterion::black_box;
60     let times = 10000usize;
61     let small = 0..times;
62     let medium = ("", 0usize, 1usize);
63     let medium = repeat(medium).take(times);
64     let large = [""; 64];
65     let large = repeat(large).take(times);
66     macro_rules! test_series {
67         ($kind:ident) => {
68             b.bench_function(stringify!(push - restore - $kind), |b| {
69                 b.iter(|| snapshot_push_restore($kind.clone()))
70             })
71             .bench_function(stringify!(push - clear - $kind), |b| {
72                 b.iter(|| snapshot_push_clear_snapshot($kind.clone()))
73             })
74             .bench_function(stringify!(pop - restore - $kind), |b| {
75                 b.iter(|| snapshot_pop_restore($kind.clone()))
76             })
77             .bench_function(stringify!(pop - clear - $kind), |b| {
78                 b.iter(|| snapshot_pop_clear($kind.clone()))
79             })
80         };
81     }
82     test_series!(small);
83     test_series!(medium);
84     test_series!(large);
85 }
86 
87 criterion_group!(benchmarks, benchmark);
88 criterion_main!(benchmarks);
89