Mercurial > lbo > hg > rcombinators
changeset 29:09d274a46fa4
Use Lazy combinator in JSON example.
Current performance: 60 µs per average long JSON message on 2.00 GHz
Intel i5 M460 in release mode.
author | Lewin Bormann <lewin@lewin-bormann.info> |
---|---|
date | Thu, 06 Jun 2019 22:28:24 +0200 |
parents | f3b758646c58 |
children | 9ef50316b2e7 |
files | examples/json/Cargo.toml examples/json/src/lib.rs |
diffstat | 2 files changed, 35 insertions(+), 20 deletions(-) [+] |
line wrap: on
line diff
--- a/examples/json/Cargo.toml Thu Jun 06 22:28:00 2019 +0200 +++ b/examples/json/Cargo.toml Thu Jun 06 22:28:24 2019 +0200 @@ -7,3 +7,4 @@ [dependencies] rcombinators = { path = "../../" } lazy_static = "1.3" +time-test = "0.1"
--- a/examples/json/src/lib.rs Thu Jun 06 22:28:00 2019 +0200 +++ b/examples/json/src/lib.rs Thu Jun 06 22:28:24 2019 +0200 @@ -1,9 +1,6 @@ //! A simplistic JSON parser library based on the `rcombinators` crate. //! -#[macro_use] -extern crate lazy_static; - use std::collections::HashMap; use std::iter::FromIterator; @@ -26,22 +23,18 @@ } } -struct PWrapper<P>(P); +#[derive(Default)] +struct ValueParser; -impl<P: Parser<Result=Value>> Parser for PWrapper<P> { +impl Parser for ValueParser { type Result = Value; - fn parse(&mut self, st: &mut ParseState<impl Iterator<Item=char>>) -> ParseResult<Self::Result> { - self.0.parse(st) - } -} - -#[derive(Default)] -struct ValueParser<P>(Option<P>); - -impl<P: Parser<Result=Value>> Parser for ValueParser<P> { - type Result = Value; - fn parse(&mut self, st: &mut ParseState<impl Iterator<Item=char>>) -> ParseResult<Self::Result> { - combinators::Alternative::new((dict(), list(), string(), number())).parse(st) + fn parse( + &mut self, + st: &mut ParseState<impl Iterator<Item = char>>, + ) -> ParseResult<Self::Result> { + let dict = combinators::Lazy::new(dict); + let list = combinators::Lazy::new(list); + combinators::Alternative::new((string(), number(), dict, list)).parse(st) } } @@ -57,12 +50,12 @@ string } -fn list<P: Parser<Result=Value>>(val: Option<PWrapper<P>>) -> impl Parser<Result = Value> { +fn list() -> impl Parser<Result = Value> { let (open, close) = ( primitives::StringParser::new("["), primitives::StringParser::new("]"), ); - let val = val; + let val = ValueParser; let comma = primitives::StringParser::new(","); let separated_element = combinators::Sequence::new(( primitives::whitespace(), @@ -89,7 +82,7 @@ Value::String(s) => Ok(s), _ => panic!("unexpected value type in string position"), }); - let value = ValueParser(None); + let value = ValueParser; let separated_element = combinators::Sequence::new(( primitives::whitespace(), key, @@ -109,6 +102,9 @@ dict } +#[macro_use] +extern crate time_test; + #[cfg(test)] mod tests { use crate::*; @@ -170,4 +166,22 @@ ])); assert_eq!(Ok(want), ValueParser.parse(&mut ps)); } + + use std::iter; + + #[test] + fn bench_value() { + let repeats = 12000; + let piece = r#"{"hello": 1.22, "world": [1, 2.3, 4, "five"], "test": "key", "lol": "ey"}"#; + let mut s = String::with_capacity(repeats * piece.len()); + s.extend(iter::repeat(piece).take(repeats)); + let mut ps = ParseState::new(&s); + let mut parser = ValueParser; + { + time_test!(); + for _ in 0..repeats { + assert!(parser.parse(&mut ps).is_ok()); + } + } + } }