use criterion::{criterion_group, criterion_main, Criterion}; use xbasic::basic_io::BasicIO; use xbasic::xbasic::XBasic; pub struct TestIO { expected: &'static str, actual: String, } impl TestIO { pub fn new(expected: &'static str) -> Self { Self { expected, actual: String::new(), } } pub fn check(&self) { assert_eq!(self.expected, self.actual); } } impl BasicIO for TestIO { fn read_line(&mut self) -> String { unimplemented!() } fn write_line(&mut self, line: String) { self.actual += &(line + "\n"); } } fn recursive_benchmark(c: &mut Criterion) { let test_io = TestIO::new(""); let mut xb = XBasic::new(test_io); c.bench_function("fib 20", |b| { b.iter(|| { xb.run( " fib(20) function fib(n) if n < 2 then return n end if return fib(n - 1) + fib(n - 2) end function ", ) }) }); } fn mandelbrot_benchmark(c: &mut Criterion) { let test_io = TestIO::new(""); let mut xb = XBasic::new(test_io); c.bench_function("mandelbrot 120x80", |b| { b.iter(|| { xb.run( " WIDTH = 120 HEIGHT = 80 MIN_X = -2 MAX_X = 1 MIN_Y = -1 MAX_Y = 1 function converges(Creal, Cimg, numIter) i = 0 zr = 0 zrtmp = 0 zi = 0 while (zr * zr + zi * zi < 4) i = i + 1 zrtemp = zr * zr + Creal - zi * zi zi = 2 * zi * zr + Cimg zr = zrtemp if i > numIter then return 0 end if wend return i end function function convertRange(ogStart, ogEnd, newStart, newEnd, value) scale = (newEnd - newStart) / (ogEnd - ogStart) return (newStart + ((value - ogStart) * scale)) end function a = 20 for x = 0 to WIDTH for y = 0 to HEIGHT cr = convertRange(0, HEIGHT, MIN_Y, MAX_Y, y) ci = convertRange(0, WIDTH, MIN_X, MAX_X, x) c = converges(ci, cr, 85) c = c * 30 if c > 0 then c = c + 30 end if a = 25 next y next x ", ) }) }); } criterion_group!(benches, recursive_benchmark, mandelbrot_benchmark); criterion_main!(benches);