Skip to content

Commit f0f87ee

Browse files
authored
Update scope to be more memory efficient (#17)
2 parents a4cc0e7 + 8004a65 commit f0f87ee

14 files changed

+447
-250
lines changed

benchmark/README.md

+32-22
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,45 @@ This directory contains the benchmarking code for the project. The benchmarking
77
On my pc:
88
```
99
Running benchmark for 'if' scripts
10-
Python: 17.039089 s for 500 iterations (avg: 0.034078 s/iter)
11-
Word: 1.779429 s for 500 iterations (avg: 0.003559 s/iter)
12-
Ratio python/word: 9.58x
10+
Python: 3.458411 s for 100 iterations (avg: 0.034584 s/iter)
11+
Word: 0.359912 s for 100 iterations (avg: 0.003599 s/iter)
12+
Ratio python/word: 9.61x
1313
1414
Running benchmark for 'while' scripts
15-
Python: 18.221854 s for 500 iterations (avg: 0.036444 s/iter)
16-
Word: 1.875409 s for 500 iterations (avg: 0.003751 s/iter)
17-
Ratio python/word: 9.72x
18-
19-
Running benchmark for 'fibonacci' scripts
20-
Python: 17.432245 s for 500 iterations (avg: 0.034864 s/iter)
21-
Word: 2.396842 s for 500 iterations (avg: 0.004794 s/iter)
22-
Ratio python/word: 7.27x
15+
Python: 3.489668 s for 100 iterations (avg: 0.034897 s/iter)
16+
Word: 0.358798 s for 100 iterations (avg: 0.003588 s/iter)
17+
Ratio python/word: 9.73x
18+
19+
Running benchmark for 'fibonacci_10' scripts
20+
Python: 3.48353 s for 100 iterations (avg: 0.034835 s/iter)
21+
Word: 0.448602 s for 100 iterations (avg: 0.004486 s/iter)
22+
Ratio python/word: 7.77x
23+
24+
Running benchmark for 'fibonacci_20' scripts
25+
Python: 3.564039 s for 100 iterations (avg: 0.03564 s/iter)
26+
Word: 7.678685 s for 100 iterations (avg: 0.076787 s/iter)
27+
Ratio python/word: 0.46x
2328
```
2429

2530
On Github Actions:
2631
```
2732
Running benchmark for 'if' scripts
28-
Python: 2.042915 s for 100 iterations (avg: 0.020429 s/iter)
29-
Word: 0.395542 s for 100 iterations (avg: 0.003955 s/iter)
30-
Ratio python/word: 5.16x
33+
Python: 1.965424 s for 100 iterations (avg: 0.019654 s/iter)
34+
Word: 0.384423 s for 100 iterations (avg: 0.003844 s/iter)
35+
Ratio python/word: 5.11x
3136
3237
Running benchmark for 'while' scripts
33-
Python: 2.008363 s for 100 iterations (avg: 0.020084 s/iter)
34-
Word: 0.376756 s for 100 iterations (avg: 0.003768 s/iter)
35-
Ratio python/word: 5.33x
36-
37-
Running benchmark for 'fibonacci' scripts
38-
Python: 2.001812 s for 100 iterations (avg: 0.020018 s/iter)
39-
Word: 0.558315 s for 100 iterations (avg: 0.005583 s/iter)
40-
Ratio python/word: 3.59x
38+
Python: 2.005564 s for 100 iterations (avg: 0.020056 s/iter)
39+
Word: 0.388103 s for 100 iterations (avg: 0.003881 s/iter)
40+
Ratio python/word: 5.17x
41+
42+
Running benchmark for 'fibonacci_10' scripts
43+
Python: 1.979016 s for 100 iterations (avg: 0.01979 s/iter)
44+
Word: 0.520043 s for 100 iterations (avg: 0.0052 s/iter)
45+
Ratio python/word: 3.81x
46+
47+
Running benchmark for 'fibonacci_20' scripts
48+
Python: 2.141 s for 100 iterations (avg: 0.02141 s/iter)
49+
Word: 13.687988 s for 100 iterations (avg: 0.13688 s/iter)
50+
Ratio python/word: 0.16x
4151
```

benchmark/benchmark.py

+24-7
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,51 @@
1-
import timeit
2-
import subprocess
3-
import sys
1+
import timeit, subprocess, sys, os
42

53
def execute_python():
6-
subprocess.run(["python", f"./scripts/{file}.py"], stdout=subprocess.DEVNULL)
4+
out = subprocess.run(["python", f"./scripts/{file}.py"], stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
5+
if out.returncode != 0:
6+
raise Exception(f"Error while executing python script [Code: {out.returncode}]\n{out.stderr.decode('utf-8')}")
77

88
def execute_word():
9-
subprocess.run(["../bin/word.exe", f"./scripts/{file}.w"], stdout=subprocess.DEVNULL)
9+
out = subprocess.run(["../bin/word.exe", f"./scripts/{file}.w"], stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
10+
if out.returncode != 0:
11+
raise Exception(f"Error while executing word script [Code: {out.returncode}]\n{out.stderr.decode('utf-8')}")
1012

1113
def execute_py_output():
1214
out = subprocess.run(["python", f"./scripts/{file}.py"], stdout=subprocess.PIPE)
15+
if out.returncode != 0:
16+
raise Exception(f"Error while executing python script [Code: {out.returncode}]\n{out.stderr.decode('utf-8')}")
1317
print(out.stdout.decode("utf-8"))
1418

1519
def execute_word_output():
1620
out = subprocess.run(["../bin/word.exe", f"./scripts/{file}.w"], stdout=subprocess.PIPE)
21+
if out.returncode != 0:
22+
raise Exception(f"Error while executing word script [Code: {out.returncode}]\n{out.stderr.decode('utf-8')}")
1723
print(out.stdout.decode("utf-8"))
1824

1925
if __name__ == "__main__":
2026
if len(sys.argv) > 1:
2127
nb_iterations = int(sys.argv[1])
2228
else:
2329
nb_iterations = 1000
24-
file_list = ["if", "while", "fibonacci"]
25-
for file in file_list:
30+
31+
#Get list of files
32+
file_list = [file.split(".")[0] for file in os.listdir("./scripts") if file.endswith(".py")]
33+
34+
for file in file_list: # Benchmark for each file
2635
print(f"Running benchmark for '{file}' scripts")
36+
37+
#Python
2738
py_time = timeit.timeit(execute_python, number=nb_iterations)
2839
print(f"Python: {round(py_time, 6)} s for {nb_iterations} iterations (avg: {round(py_time/nb_iterations, 6)} s/iter)")
40+
41+
#Word
2942
word_time = timeit.timeit(execute_word, number=nb_iterations)
3043
print(f"Word: {round(word_time, 6)} s for {nb_iterations} iterations (avg: {round(word_time/nb_iterations, 6)} s/iter)")
44+
45+
#Ratio python/word
3146
print(f"Ratio python/word: {round(py_time/word_time, 2)}x")
47+
48+
#Outputs
3249
print("Output for Python:")
3350
execute_py_output()
3451
print("Output for Word:")
File renamed without changes.
File renamed without changes.

benchmark/scripts/fibonacci_20.py

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
def fibonacci(n):
2+
if n == 0:
3+
return 0
4+
elif n == 1:
5+
return 1
6+
else:
7+
return fibonacci(n-1) + fibonacci(n-2)
8+
9+
result = fibonacci(20)
10+
print("Fibonacci of 20 is", result)

benchmark/scripts/fibonacci_20.w

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
def int fibonacci with int n
2+
if n equal 0
3+
return 0
4+
elif n equal 1
5+
return 1
6+
else
7+
call fibonacci with n minus 1 store result1
8+
call fibonacci with n minus 2 store result2
9+
return result1 plus result2
10+
endif
11+
enddef
12+
13+
call fibonacci with 20 store result
14+
print "Fibonacci of 20 is" result

bin/test.w

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
int value assign 3
1+
def int fibonacci with int n
2+
if n less 2
3+
return n
4+
else
5+
call fibonacci with n minus 1 store result1
6+
call fibonacci with n minus 2 store result2
7+
return result1 plus result2
8+
endif
9+
enddef
210

3-
if value equal 0
4-
print "Value is 0"
5-
elif value equal 1
6-
print "Value is 1"
7-
else
8-
print "Value is neither 0 nor 1"
9-
endif
11+
call fibonacci with 10 store result
12+
print result

bin/word.exe

4.41 KB
Binary file not shown.

include/interpreter.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,18 @@
55
#include <stdio.h>
66
#include "lexer.h"
77
#include "parser.h"
8+
#include "scope.h"
89
#include "w_stdlib.h"
910

1011
char *type_keywords[] = {
1112
"null", "int", "float", "str", "bool", "list",
1213
};
1314

14-
void *execute(list *parsed_code, W_Dict *args, W_Type return_type);
15+
void *execute(list *parsed_code, Scope *current_scope, W_Type return_type, bool destroy_vars_on_exit);
1516

1617
// Utility
1718

18-
void eval_parsed_lines(list_element *parsed_line, W_Dict *variables, list *stack);
19+
void eval_parsed_lines(list_element *parsed_line, Scope *scope, list *stack);
1920
char *remove_dot(W_Word *word);
2021
bool is_type_keyword(char *word);
2122
bool is_float(char *str);

include/list.h

+2
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ typedef struct _list {
2424
list *list_init();
2525
void list_append(list *l, void *value);
2626
void list_remove(list *l, int index);
27+
void *list_get(list *l, int index);
28+
void list_insert(list *l, int index, void *value);
2729
int list_size(list *l);
2830
void *list_pop(list *l);
2931
void list_destroy(list *l);

include/scope.h

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#ifndef __SCOPE_H__
2+
#define __SCOPE_H__
3+
4+
#include <stdlib.h>
5+
#include "w_type.h"
6+
#include "w_dict.h"
7+
8+
typedef struct _scope {
9+
struct _scope *parent;
10+
W_Dict *vars;
11+
} Scope;
12+
13+
Scope *init_scope();
14+
W_Var *get_var(Scope *scope, char *name);
15+
void destroy_scope(Scope *scope);
16+
17+
#endif

0 commit comments

Comments
 (0)