From 2b92cbbbec93fff31aa7c9b803c7efb7a4bd0cd1 Mon Sep 17 00:00:00 2001 From: Sebastian Schmidt Date: Thu, 29 Aug 2019 17:33:08 +0300 Subject: [PATCH] Implement benchmarks for parsing Relates to #62 --- Cargo.lock | 17 ++++++++++ Cargo.toml | 6 ++++ benches/benchs.rs | 84 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 benches/benchs.rs diff --git a/Cargo.lock b/Cargo.lock index 213d97f..ffff7f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,11 @@ dependencies = [ "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "autocfg" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "base64" version = "0.10.1" @@ -45,6 +50,7 @@ name = "evalexpr" version = "5.0.0-beta.1" dependencies = [ "rand 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)", @@ -134,6 +140,15 @@ dependencies = [ "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rand_pcg" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", + "rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "regex" version = "1.2.1" @@ -208,6 +223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [metadata] "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" +"checksum autocfg 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875" "checksum base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e" "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" @@ -224,6 +240,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum rand_chacha 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "03a2a90da8c7523f554344f921aa97283eadf6ac484a6d2a7d0212fa7f8d6853" "checksum rand_core 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" "checksum rand_hc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +"checksum rand_pcg 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e196346cbbc5c70c77e7b4926147ee8e383a38ee4d15d58a08098b169e492b6" "checksum regex 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88c3d9193984285d544df4a30c23a4e62ead42edf70a4452ceb76dac1ce05c26" "checksum regex-syntax 0.6.11 (registry+https://github.com/rust-lang/crates.io-index)" = "b143cceb2ca5e56d5671988ef8b15615733e7ee16cd348e064333b251b89343f" "checksum ron 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "17f52a24414403f81528b67488cf8edc4eda977d3af1646bb6b106a600ead78f" diff --git a/Cargo.toml b/Cargo.toml index 81b93fe..521e65d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,3 +27,9 @@ regex_support = ["regex"] [dev-dependencies] ron = "0.4" +rand = "0.7.0" +rand_pcg = "0.2.0" + +[target.bench.dependencies] +rand = "0.7.0" +rand_pcg = "0.2.0" \ No newline at end of file diff --git a/benches/benchs.rs b/benches/benchs.rs new file mode 100644 index 0000000..7b8e357 --- /dev/null +++ b/benches/benchs.rs @@ -0,0 +1,84 @@ +#![feature(test)] + +extern crate test; +extern crate rand; +extern crate rand_pcg; + +use test::Bencher; +use rand_pcg::Pcg32; +use rand::{Rng, SeedableRng}; +use rand::distributions::Uniform; +use rand::seq::SliceRandom; +use evalexpr::build_operator_tree; +use std::hint::black_box; + +const BENCHMARK_LEN: usize = 100_000; + +fn generate_expression(len: usize, gen: &mut Gen) -> String { + let int_distribution = Uniform::new_inclusive(-100, 100); + let whitespaces = vec![" ", "", "", " ", " \n", " "]; + let operators = vec!["+", "-", "*", "/", "%", "^"]; + let mut result = String::new(); + result.push_str(&format!("{}", gen.sample(int_distribution))); + + while result.len() < len { + result.push_str(whitespaces.choose(gen).unwrap()); + result.push_str(operators.choose(gen).unwrap()); + result.push_str(whitespaces.choose(gen).unwrap()); + result.push_str(&format!("{}", gen.sample(int_distribution))); + } + + result +} + +fn generate_expression_chain(len: usize, gen: &mut Gen) -> String { + let mut chain = generate_expression(10, gen); + while chain.len() < len { + chain.push_str("; "); + chain.push_str(&generate_expression(10, gen)); + } + chain +} + +fn generate_small_expressions(len: usize, gen: &mut Gen) -> Vec { + let mut result = Vec::new(); + let mut result_len = 0; + while result_len < len { + let expression = generate_expression(10, gen); + result_len += expression.len(); + result.push(expression); + } + result +} + +#[bench] +fn bench_parse_long_expression_chains(bencher: &mut Bencher) { + let mut gen = Pcg32::seed_from_u64(0); + let long_expression_chain = generate_expression_chain(BENCHMARK_LEN, &mut gen); + + bencher.iter(|| { + build_operator_tree(&long_expression_chain).unwrap() + }); +} + +#[bench] +fn bench_parse_deep_expression_trees(bencher: &mut Bencher) { + let mut gen = Pcg32::seed_from_u64(15); + let deep_expression_tree = generate_expression(BENCHMARK_LEN, &mut gen); + + bencher.iter(|| { + build_operator_tree(&deep_expression_tree).unwrap() + }); +} + +#[bench] +fn bench_parse_many_small_expressions(bencher: &mut Bencher) { + let mut gen = Pcg32::seed_from_u64(33); + let small_expressions = generate_small_expressions(BENCHMARK_LEN, &mut gen); + + bencher.iter(|| { + for expression in &small_expressions { + black_box(build_operator_tree(&expression).unwrap()); + } + }); +} \ No newline at end of file