From 8412b0ec40e8457a182517abb42059200b262c2c Mon Sep 17 00:00:00 2001 From: David Krentzlin Date: Sat, 4 Sep 2021 11:21:48 +0200 Subject: [PATCH] Setup benchmarks and vm smoke test (#26) --- Cargo.toml | 4 ++ benches/compiler_benchmark.rs | 11 +++- benches/vm_benchmark.rs | 32 +++++++++++ examples/fib.scm | 11 ++-- tests/vm_tests.rs | 102 ++++++++++++++++++++-------------- 5 files changed, 112 insertions(+), 48 deletions(-) create mode 100644 benches/vm_benchmark.rs diff --git a/Cargo.toml b/Cargo.toml index 26db7b2..77d371a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,6 +22,10 @@ path="src/lib.rs" name="compiler_benchmark" harness=false +[[bench]] +name="vm_benchmark" +harness=false + [features] debug_vm = [] debug_code = [] diff --git a/benches/compiler_benchmark.rs b/benches/compiler_benchmark.rs index 5a81b65..17680fb 100644 --- a/benches/compiler_benchmark.rs +++ b/benches/compiler_benchmark.rs @@ -4,7 +4,16 @@ use criterion::{black_box, criterion_group, criterion_main, Criterion}; fn compiler_benchmark(c: &mut Criterion) { let mut compiler = Compiler::new(); - let mut source = StringSource::new("#true"); + let mut source = StringSource::new( + r#" + (define (add x y) (+ x y)) + (define (minus x y) (- x y)) + + (add 10 20) + ; this is a comment + (sub 20 10) + "#, + ); c.bench_function("compile_expression", |b| { b.iter(|| compiler.compile(black_box(&mut source))) diff --git a/benches/vm_benchmark.rs b/benches/vm_benchmark.rs new file mode 100644 index 0000000..52a7ad9 --- /dev/null +++ b/benches/vm_benchmark.rs @@ -0,0 +1,32 @@ +use braces::compiler::source::*; +use braces::compiler::Compiler; +use braces::vm::VM; +use criterion::{black_box, criterion_group, criterion_main, Criterion}; + +fn vm_fibonacci_benchmark(c: &mut Criterion) { + let mut source = StringSource::new( + r#" + (define (fib-tc n) + (fib-iter 1 0 n)) + + (define (fib-iter a b count) + (if (= count 0) + b + (fib-iter (+ a b) a (- count 1)))) + + (define (fib n) (if (<= n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) + + (fib 15) + "#, + ); + let mut vm = VM::default(); + let mut compiler = Compiler::new(); + let unit = compiler.compile(&mut source).unwrap(); + + c.bench_function("interpret_fibonacci", |b| { + b.iter(|| vm.interpret(unit.clone())) + }); +} + +criterion_group!(benches, vm_fibonacci_benchmark); +criterion_main!(benches); diff --git a/examples/fib.scm b/examples/fib.scm index 2e887cb..edf1923 100644 --- a/examples/fib.scm +++ b/examples/fib.scm @@ -1,12 +1,11 @@ -(define fib-tc (lambda (n) - (fib-iter 1 0 n))) +(define (fib-tc n) + (fib-iter 1 0 n)) -(define fib-iter (lambda (a b count) +(define (fib-iter a b count) (if (= count 0) b - (fib-iter (+ a b) a (- count 1))))) + (fib-iter (+ a b) a (- count 1)))) - -(define fib (lambda (n) (if (<= n 2) 1 (+ (fib (- n 1)) (fib (- n 2)))))) +(define (fib n) (if (<= n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) (fib 10) diff --git a/tests/vm_tests.rs b/tests/vm_tests.rs index cc9f19e..74fa468 100644 --- a/tests/vm_tests.rs +++ b/tests/vm_tests.rs @@ -88,7 +88,6 @@ fn test_vm_lexical_scope() { fn test_vm_set() { let mut vm = VM::default(); - /* let result = run_code(&mut vm, "(begin (set! x #t) x)"); assert_matches!( result, @@ -98,7 +97,7 @@ fn test_vm_set() { _, _ )) - ); */ + ); let result = run_code(&mut vm, r#"((lambda (foo) (set! foo 'bar) foo) #t)"#).unwrap(); assert_eq!(result, vm.values.symbol("bar")); @@ -212,11 +211,8 @@ fn test_vm_conditional() { let mut vm = VM::default(); assert_result_eq(&mut vm, "(if #f #t #f)", Value::Bool(false)); - assert_result_eq(&mut vm, "(if #t #t #f)", Value::Bool(true)); - assert_result_eq(&mut vm, "(if #f #t)", Value::Unspecified); - assert_result_eq(&mut vm, "(if #t #t)", Value::Bool(true)); } @@ -225,13 +221,13 @@ fn test_vm_simple_closures() { let mut vm = VM::default(); let result = run_code( &mut vm, - " - (define test - ((lambda (x y) (lambda () (set! x (not x)) x)) #t 'ignored) - ) - (define ls (lambda x x)) - (ls (test) (test) (test)) -", + r#" + (define test + ((lambda (x y) (lambda () (set! x (not x)) x)) #t 'ignored) + ) + (define ls (lambda x x)) + (ls (test) (test) (test)) + "#, ) .unwrap(); @@ -246,25 +242,25 @@ fn test_vm_simple_closures() { let result = run_code( &mut vm, - " - (define test - ((lambda (x y) (lambda () x)) #t 'ignored) - ) - (test) -", + r#" + (define test + ((lambda (x y) (lambda () x)) #t 'ignored) + ) + (test) + "#, ) .unwrap(); assert_eq!(result, vm.values.bool_true()); let result = run_code( &mut vm, - " - (define test - ((lambda (x) - ((lambda (proc) (set! x #f) proc) (lambda () x))) + r#" + (define test + ((lambda (x) + ((lambda (proc) (set! x #f) proc) (lambda () x))) #t)) - (test) -", + (test) + "#, ) .unwrap(); assert_eq!(result, vm.values.bool_false()); @@ -275,18 +271,18 @@ fn test_vm_complex_closures() { let mut vm = VM::default(); let result = run_code( &mut vm, - " - (define list (lambda ls ls)) - (define set-x #t) - (define get-x #t) - (define make-closures (lambda (value) - ((lambda (x) - (set! get-x (lambda () x)) - (set! set-x (lambda (new) (set! x new)))) value))) - - (make-closures #t) - (list (get-x) (set-x 'foo) (get-x)) -", + r#" + (define list (lambda ls ls)) + (define set-x #t) + (define get-x #t) + (define make-closures (lambda (value) + ((lambda (x) + (set! get-x (lambda () x)) + (set! set-x (lambda (new) (set! x new)))) value))) + + (make-closures #t) + (list (get-x) (set-x 'foo) (get-x)) + "#, ) .unwrap(); @@ -301,6 +297,30 @@ fn test_vm_complex_closures() { ); } +#[test] +fn test_vm_smoke_test() { + let mut vm = VM::default(); + + let result = run_code( + &mut vm, + r#" + (define (fib-tc n) + (fib-iter 1 0 n)) + + (define (fib-iter a b count) + (if (= count 0) + b + (fib-iter (+ a b) a (- count 1)))) + + (define (fib n) (if (<= n 2) 1 (+ (fib (- n 1)) (fib (- n 2))))) + + (fib 10) + "#, + ) + .unwrap(); + assert_eq!(result, vm.values.real(55)); +} + #[test] fn test_vm_bugs() { let mut vm = VM::default(); @@ -308,11 +328,11 @@ fn test_vm_bugs() { // results in arity error let result = run_code( &mut vm, - " - (define ls (lambda x x)) - (define test (lambda () #t)) - (ls (test) #f (test)) -", + r#" + (define ls (lambda x x)) + (define test (lambda () #t)) + (ls (test) #f (test)) + "#, ) .unwrap();