aboutsummaryrefslogtreecommitdiff
path: root/benches/iter.rs
blob: 0a0d5ff3dec0139ecfa529e39e0542d0adf812c6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
use criterion::black_box;

use winnow::combinator::opt;
use winnow::prelude::*;
use winnow::stream::AsChar;
use winnow::stream::Stream as _;
use winnow::token::one_of;

fn iter(c: &mut criterion::Criterion) {
    let data = [
        ("contiguous", CONTIGUOUS.as_bytes()),
        ("interleaved", INTERLEAVED.as_bytes()),
        ("canada", CANADA.as_bytes()),
    ];
    let mut group = c.benchmark_group("iter");
    for (name, sample) in data {
        let len = sample.len();
        group.throughput(criterion::Throughput::Bytes(len as u64));

        group.bench_with_input(
            criterion::BenchmarkId::new("iterate", name),
            &len,
            |b, _| {
                b.iter(|| black_box(iterate.parse_peek(black_box(sample)).unwrap()));
            },
        );
        group.bench_with_input(
            criterion::BenchmarkId::new("next_token", name),
            &len,
            |b, _| {
                b.iter(|| black_box(next_token.parse_peek(black_box(sample)).unwrap()));
            },
        );
        group.bench_with_input(
            criterion::BenchmarkId::new("opt(one_of)", name),
            &len,
            |b, _| {
                b.iter(|| black_box(opt_one_of.parse_peek(black_box(sample)).unwrap()));
            },
        );
        group.bench_with_input(
            criterion::BenchmarkId::new("take_while", name),
            &len,
            |b, _| {
                b.iter(|| black_box(take_while.parse_peek(black_box(sample)).unwrap()));
            },
        );
        group.bench_with_input(criterion::BenchmarkId::new("repeat", name), &len, |b, _| {
            b.iter(|| black_box(repeat.parse_peek(black_box(sample)).unwrap()));
        });
    }
    group.finish();
}

fn iterate(input: &mut &[u8]) -> PResult<usize> {
    let mut count = 0;
    for byte in input.iter() {
        if byte.is_dec_digit() {
            count += 1;
        }
    }
    input.finish();
    Ok(count)
}

fn next_token(input: &mut &[u8]) -> PResult<usize> {
    let mut count = 0;
    while let Some(byte) = input.next_token() {
        if byte.is_dec_digit() {
            count += 1;
        }
    }
    Ok(count)
}

fn opt_one_of(input: &mut &[u8]) -> PResult<usize> {
    let mut count = 0;
    while !input.is_empty() {
        while opt(one_of(AsChar::is_dec_digit))
            .parse_next(input)?
            .is_some()
        {
            count += 1;
        }
        while opt(one_of(|b: u8| !b.is_dec_digit()))
            .parse_next(input)?
            .is_some()
        {}
    }
    Ok(count)
}

fn take_while(input: &mut &[u8]) -> PResult<usize> {
    let mut count = 0;
    while !input.is_empty() {
        count += winnow::token::take_while(0.., AsChar::is_dec_digit)
            .parse_next(input)?
            .len();
        let _ = winnow::token::take_while(0.., |b: u8| !b.is_dec_digit()).parse_next(input)?;
    }
    Ok(count)
}

fn repeat(input: &mut &[u8]) -> PResult<usize> {
    let mut count = 0;
    while !input.is_empty() {
        count += winnow::combinator::repeat(0.., one_of(AsChar::is_dec_digit))
            .map(|count: usize| count)
            .parse_next(input)?;
        winnow::combinator::repeat(0.., one_of(|b: u8| !b.is_dec_digit())).parse_next(input)?;
    }
    Ok(count)
}

const CONTIGUOUS: &str = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789";
const INTERLEAVED: &str = "0123456789abc0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab0123456789ab";
const CANADA: &str = include_str!("../third_party/nativejson-benchmark/data/canada.json");

criterion::criterion_group!(benches, iter);
criterion::criterion_main!(benches);