use crate::prelude::*;
extern crate test;
use test::{black_box, Bencher};
#[allow(unused)]
fn bench_execute<'a>(
b: &mut Bencher,
src: &str,
func: &str,
args: &'a mut [RuntimeValue<'a>],
expected: RuntimeValue<'a>,
) {
let ast = Parser::new().parse(src).unwrap();
let program = CodeGenerator::new().generate_program(&ast).unwrap();
let mut vm = VirtualMachine::new(&program)
.with_type_casting()
.with_max_instructions(None)
.with_max_stack_depth(None);
b.iter(move || {
let result = black_box(&mut vm)
.call(black_box(func), black_box(args))
.unwrap();
assert_eq!(result, expected);
})
}
#[bench]
#[cfg(feature = "bool_type")]
fn fn_call_overhead(b: &mut Bencher) {
let src = r#"
fn simple(a) {
a
}
fn decoy1(a) {
!a
}
fn decoy2(a) {
!a
}
"#;
bench_execute(
b,
src,
"simple",
&mut [RuntimeValue::Value(Value::Bool(true))],
RuntimeValue::Value(Value::Bool(true)),
);
}
#[bench]
#[cfg(all(feature = "bool_type", feature = "i32_type"))]
fn host_call_overhead(b: &mut Bencher) {
let src = r#"
fn simple(a) {
i32(a)
}
"#;
bench_execute(
b,
src,
"simple",
&mut [RuntimeValue::Value(Value::Bool(true))],
RuntimeValue::Value(Value::I32(1)),
);
}
#[bench]
#[cfg(feature = "bool_type")]
fn new_vm_overhead(b: &mut Bencher) {
let src = r#"
fn simple(a) {
a
}
"#;
let ast = Parser::new().parse(src).unwrap();
let program = CodeGenerator::new().generate_program(&ast).unwrap();
b.iter(move || {
let mut vm = VirtualMachine::new(&program)
.with_type_casting()
.with_max_instructions(None)
.with_max_stack_depth(None);
let result = black_box(&mut vm)
.call(
black_box("simple"),
black_box(&mut [RuntimeValue::Value(Value::Bool(true))]),
)
.unwrap();
assert_eq!(result, RuntimeValue::Value(Value::Bool(true)));
});
}
#[bench]
#[cfg(all(feature = "while_loop", feature = "i32_type"))]
fn million_iterations(b: &mut Bencher) {
let src = r#"
fn million() {
let x = 1000000;
while x > 0 {
x = x - 1;
}
}
"#;
bench_execute(b, src, "million", &mut [], RuntimeValue::Value(Value::Null));
}
#[bench]
#[cfg(all(
feature = "if_expression",
feature = "while_loop",
feature = "i32_type"
))]
fn fib_28(b: &mut test::Bencher) {
let src = r#"
fn fib(n) {
if n < 2 {
n
} else {
fib(n-1) + fib(n-2)
}
}
fn five(n) {
let i = 0;
let ret = 0;
while (i < 5) {
ret = fib(n);
i = i + 1;
}
ret
}
"#;
bench_execute(
b,
src,
"five",
&mut [RuntimeValue::Value(Value::I32(28))],
RuntimeValue::Value(Value::I32(317811)),
);
}