Performance
Below you will find a table of benchmark information for each of the 4
implementations. There are two benchmarks for each implementation, the first is parsing just 1 duration, the second is parsing 1000 durations, these are all created using lazy_static
so each parser is provided the same input. For the build time and build size benchmarks, I used the following binary application with feature flags to conditionally use each of the implementations.
extern crate duration; extern crate random_durations; #[cfg(all(feature = "nom", not(feature = "bench")))] extern crate nom_duration_parser as parser; #[cfg(all(feature = "combine", not(feature = "bench")))] extern crate combine_duration_parser as parser; #[cfg(all(feature = "pest", not(feature = "bench")))] extern crate pest_duration_parser as parser; #[cfg(all(feature = "hand", not(feature = "bench")))] extern crate hand_rolled_duration_parser as parser; #[cfg(any(feature = "bench", not(any(feature = "nom", feature = "combine", feature = "pest", feature = "hand"))))] fn main() { println!("{}", random_durations::gen_random_durs_text(get_count()).join("\n")); } #[cfg( all( any(feature = "nom", feature = "combine", feature = "pest", feature = "hand"), not(feature = "bench") ) )] fn main() { for d in random_durations::gen_random_durs(get_count()) { let s = format!("{}", d); let p = parser::parse(&s).unwrap(); assert_eq!(d, p); println!("duration:{}\nparsed to\n{}", d, p.human_readable()); } } fn get_count() -> usize { for arg in ::std::env::args() { match arg.parse() { Ok(u) => return u, Err(_) => () } } return 1000 }
Build time
This is the time it took to run cargo build
on each implementation. With the increasing improvement of incremental compilation, it isn't the most important metric but some people might care about it.
Bin size
This is the size of the program when built using cargo build --release
.
Parse 1
This is the time cargo +nightly bench
reported for this parser to parse 1 duration.
Parse 1000
This is the time cargo +nightly bench
reported for this parser to parse 1000 durations.
Benches
# #![allow(unused_variables)] #![feature(test)] #fn main() { extern crate test; extern crate duration; extern crate random_durations; #[cfg(feature = "nom")] extern crate nom_duration_parser; #[cfg(feature = "pest")] extern crate pest_duration_parser; #[cfg(feature = "combine")] extern crate combine_duration_parser; #[cfg(feature = "hand")] extern crate hand_rolled_duration_parser; #[macro_use] extern crate lazy_static; use test::{Bencher, black_box}; use duration::Duration; lazy_static! { static ref DURATION: String = format!("{}", random_durations::gen_random_dur()); } lazy_static! { static ref DURATIONS: Vec<String> = random_durations::gen_random_durs_text(1000); } #[cfg(feature = "nom")] #[bench] fn nom(b: &mut Bencher) { single(b, &nom_duration_parser::parse); } #[cfg(feature = "nom")] #[bench] fn nom_1000(b: &mut Bencher) { thousand(b, &nom_duration_parser::parse); } #[cfg(feature = "pest")] #[bench] fn pest(b: &mut Bencher) { single(b, &pest_duration_parser::parse); } #[cfg(feature = "pest")] #[bench] fn pest_1000(b: &mut Bencher) { thousand(b, &pest_duration_parser::parse); } #[cfg(feature = "combine")] #[bench] fn combine(b: &mut Bencher) { single(b, &combine_duration_parser::parse); } #[cfg(feature = "combine")] #[bench] fn combine_1000(b: &mut Bencher) { thousand(b, &combine_duration_parser::parse); } #[cfg(feature = "hand")] #[bench] fn hand_rolled(b: &mut Bencher) { single(b, &hand_rolled_duration_parser::parse); } #[cfg(feature = "hand")] #[bench] fn hand_rolled_1000(b: &mut Bencher) { thousand(b, &hand_rolled_duration_parser::parse); } fn single(b: &mut Bencher, f: &impl Fn(&str) -> Result<Duration, String>) { b.iter(|| { black_box(f(&DURATION).unwrap()); }); } fn thousand(b: &mut Bencher, f: &impl Fn(&str) -> Result<Duration, String>) { b.iter(|| { for s in DURATIONS.iter() { black_box(f(s).unwrap()); } }) } #}
crate | parse 1 (+/-) | parse 1000 (+/-) | build time | release size |
---|---|---|---|---|
nom | 363.00ns (10.00ns) | 844.53ms (64.04ms) | 6.98s | 727.08 kb |
combine | 1.19ms (51.00ns) | 3.92s (276.65ms) | 21.40s | 739.68 kb |
pest | 5.13ms (126.00ns) | 4.05s (93.54ms) | 19.22s | 767.86 kb |
hand_rolled | 205.00ns (1.00ns) | 541.68ms (21.55ms) | 7.22s | 718.87 kb |