1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::time::Instant;

use crate::{
    ast::Nodetrait,
    bytecode_vm::{bytecode::compiler::Compiler, vm::VM},
    heap::Heap,
    lexer::Lexer,
    object::environment::Environment,
    parser::Parser,
    treewalker::eval::evaluate,
};

pub fn benchmark() {
    println!("start benchmark\n");

    let fibo = "
let fibonacci = fn(x) {
    if (x == 0) {
        0
    } else {
        if (x == 1) {
            return 1;
        } else {
            fibonacci(x - 1) + fibonacci(x - 2)
        }
    }
};
fibonacci(25);
"
    .to_string();
    println!("parsing: {}", fibo);

    let start_time = Instant::now();

    let lex = Lexer::new(fibo);
    let mut parser = Parser::new(lex);
    let program = parser.parse().unwrap();

    let parsed_time = start_time.elapsed();
    println!("parse_time : {:?}", parsed_time);

    let comp_rst = Compiler::create();
    if comp_rst.as_ref().is_err() {
        panic!("Error have been occurred {:?}", comp_rst.unwrap());
    }

    let mut comp = comp_rst.unwrap();
    let compile_start = Instant::now();

    comp.compile(program.clone());

    let compile_time = compile_start.elapsed();

    println!("compile_time : {:?}", compile_time);

    let bytecode_rst = comp.bytecode();
    let bytecode = bytecode_rst.unwrap();

    let mut vm = VM::new(bytecode);
    let vm_start = Instant::now();
    println!("\n\nLaunching VM...");
    while vm.is_runable() {
        if let Err(vm_err) = vm.run_single() {
            panic!("Error have been occurred {:?}", vm_err);
        }
    }
    let vm_time = vm_start.elapsed();

    println!("vm_time : {:?}\nvm_result : {:?}", vm_time, vm.last_pop());

    let mut env = Environment::new();
    let mut heap = Heap::new();
    let eval_start = Instant::now();
    println!("\n\nLaunching Evaluator...");
    let result = evaluate(program.to_node(), &mut heap, &mut env);
    let eval_time = eval_start.elapsed();

    println!("eval_time : {:?}\neval_result : {:?}", eval_time, result);

    println!(
        "eval_time/vm_time : {:?}",
        eval_time.as_secs_f64() / vm_time.as_secs_f64()
    );
}