diff --git a/benches/eval_expression.rs b/benches/eval_expression.rs new file mode 100644 index 00000000..131d3bb5 --- /dev/null +++ b/benches/eval_expression.rs @@ -0,0 +1,43 @@ +#![feature(test)] + +///! Test evaluating expressions +extern crate test; + +use rhai::{Engine, OptimizationLevel}; +use test::Bencher; + +#[bench] +fn bench_eval_expression_single(bench: &mut Bencher) { + let script = "1"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let ast = engine.compile_expression(script).unwrap(); + + bench.iter(|| engine.consume_ast(&ast).unwrap()); +} + +#[bench] +fn bench_eval_expression_number_literal(bench: &mut Bencher) { + let script = "2 > 1"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let ast = engine.compile_expression(script).unwrap(); + + bench.iter(|| engine.consume_ast(&ast).unwrap()); +} + +#[bench] +fn bench_eval_expression_number_operators(bench: &mut Bencher) { + let script = "2 + 2 == 4"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let ast = engine.compile_expression(script).unwrap(); + + bench.iter(|| engine.consume_ast(&ast).unwrap()); +} diff --git a/benches/eval_scope.rs b/benches/eval_scope.rs new file mode 100644 index 00000000..5d38f7d7 --- /dev/null +++ b/benches/eval_scope.rs @@ -0,0 +1,77 @@ +#![feature(test)] + +///! Test evaluating with scope +extern crate test; + +use rhai::{Engine, OptimizationLevel, Scope, INT}; +use test::Bencher; + +#[bench] +fn bench_eval_scope_single(bench: &mut Bencher) { + let script = "requests_made == requests_made"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let mut scope = Scope::new(); + scope.push("requests_made", 99 as INT); + + let ast = engine.compile_expression(script).unwrap(); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} + +#[bench] +fn bench_eval_scope_multiple(bench: &mut Bencher) { + let script = "requests_made > requests_succeeded"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let mut scope = Scope::new(); + scope.push("requests_made", 99 as INT); + scope.push("requests_succeeded", 90 as INT); + + let ast = engine.compile_expression(script).unwrap(); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} + +#[bench] +fn bench_eval_scope_longer(bench: &mut Bencher) { + let script = "(requests_made * requests_succeeded / 100) >= 90"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let mut scope = Scope::new(); + scope.push("requests_made", 99 as INT); + scope.push("requests_succeeded", 90 as INT); + + let ast = engine.compile_expression(script).unwrap(); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} + +#[bench] +fn bench_eval_scope_complex(bench: &mut Bencher) { + let script = r#" + 2 > 1 && + "something" != "nothing" || + "2014-01-20" < "Wed Jul 8 23:07:35 MDT 2015" && + Variable_name_with_spaces <= variableName && + modifierTest + 1000 / 2 > (80 * 100 % 2) + "#; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let mut scope = Scope::new(); + scope.push("Variable_name_with_spaces", 99 as INT); + scope.push("variableName", 90 as INT); + scope.push("modifierTest", 5 as INT); + + let ast = engine.compile_expression(script).unwrap(); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} diff --git a/benches/eval_type.rs b/benches/eval_type.rs new file mode 100644 index 00000000..1e5a70c8 --- /dev/null +++ b/benches/eval_type.rs @@ -0,0 +1,100 @@ +#![feature(test)] + +///! Test evaluating expressions +extern crate test; + +use rhai::{Engine, OptimizationLevel, RegisterFn, Scope, INT}; +use test::Bencher; + +#[derive(Debug, Clone)] +struct Test { + x: INT, +} + +impl Test { + pub fn get_x(&mut self) -> INT { + self.x + } + pub fn action(&mut self) { + self.x = 0; + } + pub fn update(&mut self, val: INT) { + self.x = val; + } + pub fn get_nest(&mut self) -> Test { + Test { x: 9 } + } +} + +#[bench] +fn bench_type_field(bench: &mut Bencher) { + let script = "foo.field"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + engine.register_type_with_name::("Test"); + engine.register_get("field", Test::get_x); + + let ast = engine.compile_expression(script).unwrap(); + + let mut scope = Scope::new(); + scope.push("foo", Test { x: 42 }); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} + +#[bench] +fn bench_type_method(bench: &mut Bencher) { + let script = "foo.action()"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + engine.register_type_with_name::("Test"); + engine.register_fn("action", Test::action); + + let ast = engine.compile_expression(script).unwrap(); + + let mut scope = Scope::new(); + scope.push("foo", Test { x: 42 }); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} + +#[bench] +fn bench_type_method_with_params(bench: &mut Bencher) { + let script = "foo.update(1)"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + engine.register_type_with_name::("Test"); + engine.register_fn("update", Test::update); + + let ast = engine.compile_expression(script).unwrap(); + + let mut scope = Scope::new(); + scope.push("foo", Test { x: 42 }); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} + +#[bench] +fn bench_type_method_nested(bench: &mut Bencher) { + let script = "foo.nest.field"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + engine.register_type_with_name::("Test"); + engine.register_get("field", Test::get_x); + engine.register_get("nest", Test::get_nest); + + let ast = engine.compile_expression(script).unwrap(); + + let mut scope = Scope::new(); + scope.push("foo", Test { x: 42 }); + + bench.iter(|| engine.consume_ast_with_scope(&mut scope, &ast).unwrap()); +} diff --git a/benches/iterations.rs b/benches/iterations.rs new file mode 100644 index 00000000..31da75f3 --- /dev/null +++ b/benches/iterations.rs @@ -0,0 +1,25 @@ +#![feature(test)] + +///! Test 1,000 iterations +extern crate test; + +use rhai::{Engine, OptimizationLevel}; +use test::Bencher; + +#[bench] +fn bench_iterations_1000(bench: &mut Bencher) { + let script = r#" + let x = 1_000; + + while x > 0 { + x = x - 1; + } + "#; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + let ast = engine.compile(script).unwrap(); + + bench.iter(|| engine.consume_ast(&ast).unwrap()); +} diff --git a/benches/parsing.rs b/benches/parsing.rs new file mode 100644 index 00000000..280b9f45 --- /dev/null +++ b/benches/parsing.rs @@ -0,0 +1,83 @@ +#![feature(test)] + +///! Test parsing expressions +extern crate test; + +use rhai::{Engine, OptimizationLevel}; +use test::Bencher; + +#[bench] +fn bench_parse_single(bench: &mut Bencher) { + let script = "1"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + bench.iter(|| engine.compile_expression(script).unwrap()); +} + +#[bench] +fn bench_parse_simple(bench: &mut Bencher) { + let script = "(requests_made * requests_succeeded / 100) >= 90"; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + bench.iter(|| engine.compile_expression(script).unwrap()); +} + +#[bench] +fn bench_parse_full(bench: &mut Bencher) { + let script = r#" + 2 > 1 && + "something" != "nothing" || + "2014-01-20" < "Wed Jul 8 23:07:35 MDT 2015" && + [array, with, spaces].len() <= #{prop:name}.len() && + modifierTest + 1000 / 2 > (80 * 100 % 2) + "#; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + bench.iter(|| engine.compile_expression(script).unwrap()); +} + +#[bench] +fn bench_parse_primes(bench: &mut Bencher) { + let script = r#" + // This script uses the Sieve of Eratosthenes to calculate prime numbers. + + let now = timestamp(); + + const MAX_NUMBER_TO_CHECK = 10_000; // 1229 primes <= 10000 + + let prime_mask = []; + prime_mask.pad(MAX_NUMBER_TO_CHECK, true); + + prime_mask[0] = prime_mask[1] = false; + + let total_primes_found = 0; + + for p in range(2, MAX_NUMBER_TO_CHECK) { + if prime_mask[p] { + print(p); + + total_primes_found += 1; + let i = 2 * p; + + while i < MAX_NUMBER_TO_CHECK { + prime_mask[i] = false; + i += p; + } + } + } + + print("Total " + total_primes_found + " primes."); + print("Run time = " + now.elapsed() + " seconds."); + "#; + + let mut engine = Engine::new(); + engine.set_optimization_level(OptimizationLevel::None); + + bench.iter(|| engine.compile(script).unwrap()); +}