diff --git a/bench/fib.lox b/bench/fib.lox new file mode 100644 index 0000000..b28655b --- /dev/null +++ b/bench/fib.lox @@ -0,0 +1,10 @@ +fun fib(n) { + if (n < 2) return n; + return fib(n - 1) + fib(n - 2); +} + +var before = clock(); +print fib(40); +var after = clock(); +print "Time elapsed (ms):"; +print after - before; \ No newline at end of file diff --git a/bench/fib33.lox b/bench/fib33.lox new file mode 100644 index 0000000..5174edd --- /dev/null +++ b/bench/fib33.lox @@ -0,0 +1,10 @@ +fun fib(n) { + if (n < 2) return n; + return fib(n - 1) + fib(n - 2); +} + +var before = clock(); +print fib(33); +var after = clock(); +print "Time elapsed (ms):"; +print after - before; diff --git a/package.json b/package.json index f5c440b..fd626df 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "README.md" ], "scripts": { + "benchmark": "pnpm --silent run repl bench/fib33.lox", "build": "tsup", "coverage": "pnpm test -- --coverage --no-watch", "format": "prettier \"**/*\" --ignore-unknown", diff --git a/src/interpreter.ts b/src/interpreter.ts index 4aab1b2..5415e6f 100644 --- a/src/interpreter.ts +++ b/src/interpreter.ts @@ -8,10 +8,9 @@ import { CurrencyValue, LoxValue, isCurrency } from "./lox-value.js"; import { runtimeError } from "./main.js"; import { Token } from "./token.js"; -export class ReturnCall extends Error { +export class ReturnCall { value: LoxValue; constructor(value: LoxValue) { - super(); this.value = value; } } @@ -286,6 +285,9 @@ export class Interpreter { case "return": { const value = stmt.value && this.evaluate(stmt.value); + // While it's bad practice to throw something other than an Error subclass, + // doing so here result in a ~5x speedup on the Fibonacci benchmark. + // eslint-disable-next-line @typescript-eslint/no-throw-literal throw new ReturnCall(value); }