• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #[global_allocator]
2 static ALLOC: jemallocator::Jemalloc = jemallocator::Jemalloc;
3 
4 use criterion::*;
5 
6 use nom::{
7   bytes::complete::take_while,
8   character::complete::{
9     alphanumeric1 as alphanumeric, char, multispace1 as multispace, space1 as space,
10   },
11   combinator::{map, map_res, opt},
12   multi::many0,
13   sequence::{delimited, pair, separated_pair, terminated, tuple},
14   IResult,
15 };
16 use std::collections::HashMap;
17 use std::str;
18 
category(i: &[u8]) -> IResult<&[u8], &str>19 fn category(i: &[u8]) -> IResult<&[u8], &str> {
20   map_res(
21     delimited(char('['), take_while(|c| c != b']'), char(']')),
22     str::from_utf8,
23   )(i)
24 }
25 
key_value(i: &[u8]) -> IResult<&[u8], (&str, &str)>26 fn key_value(i: &[u8]) -> IResult<&[u8], (&str, &str)> {
27   let (i, key) = map_res(alphanumeric, str::from_utf8)(i)?;
28   let (i, _) = tuple((opt(space), char('='), opt(space)))(i)?;
29   let (i, val) = map_res(take_while(|c| c != b'\n' && c != b';'), str::from_utf8)(i)?;
30   let (i, _) = opt(pair(char(';'), take_while(|c| c != b'\n')))(i)?;
31   Ok((i, (key, val)))
32 }
33 
categories(i: &[u8]) -> IResult<&[u8], HashMap<&str, HashMap<&str, &str>>>34 fn categories(i: &[u8]) -> IResult<&[u8], HashMap<&str, HashMap<&str, &str>>> {
35   map(
36     many0(separated_pair(
37       category,
38       opt(multispace),
39       map(
40         many0(terminated(key_value, opt(multispace))),
41         |vec: Vec<_>| vec.into_iter().collect(),
42       ),
43     )),
44     |vec: Vec<_>| vec.into_iter().collect(),
45   )(i)
46 }
47 
bench_ini(c: &mut Criterion)48 fn bench_ini(c: &mut Criterion) {
49   let str = "[owner]
50 name=John Doe
51 organization=Acme Widgets Inc.
52 
53 [database]
54 server=192.0.2.62
55 port=143
56 file=payroll.dat
57 \0";
58 
59   let mut group = c.benchmark_group("ini");
60   group.throughput(Throughput::Bytes(str.len() as u64));
61   group.bench_function(BenchmarkId::new("parse", str.len()), |b| {
62     b.iter(|| categories(str.as_bytes()).unwrap())
63   });
64 }
65 
bench_ini_keys_and_values(c: &mut Criterion)66 fn bench_ini_keys_and_values(c: &mut Criterion) {
67   let str = "server=192.0.2.62
68 port=143
69 file=payroll.dat
70 \0";
71 
72   fn acc(i: &[u8]) -> IResult<&[u8], Vec<(&str, &str)>> {
73     many0(key_value)(i)
74   }
75 
76   let mut group = c.benchmark_group("ini keys and values");
77   group.throughput(Throughput::Bytes(str.len() as u64));
78   group.bench_function(BenchmarkId::new("parse", str.len()), |b| {
79     b.iter(|| acc(str.as_bytes()).unwrap())
80   });
81 }
82 
bench_ini_key_value(c: &mut Criterion)83 fn bench_ini_key_value(c: &mut Criterion) {
84   let str = "server=192.0.2.62\n";
85 
86   let mut group = c.benchmark_group("ini key value");
87   group.throughput(Throughput::Bytes(str.len() as u64));
88   group.bench_function(BenchmarkId::new("parse", str.len()), |b| {
89     b.iter(|| key_value(str.as_bytes()).unwrap())
90   });
91 }
92 
93 criterion_group!(
94   benches,
95   bench_ini,
96   bench_ini_keys_and_values,
97   bench_ini_key_value
98 );
99 criterion_main!(benches);
100