Skip to content

JS runtime: Use classes for Ref and Arena instead of closures#1332

Merged
jiribenes merged 1 commit intomainfrom
experiment/js/arena-as-a-class
Mar 23, 2026
Merged

JS runtime: Use classes for Ref and Arena instead of closures#1332
jiribenes merged 1 commit intomainfrom
experiment/js/arena-as-a-class

Conversation

@jiribenes
Copy link
Copy Markdown
Contributor

@jiribenes jiribenes commented Mar 21, 2026

Previously, we:

  1. for each var, we allocated a new closure for its own set method
  2. for each RESET, we allocated two closures for their fresh and arena methods

... what if we, uh, didn't do that?


This could have been resolved both with prototypes and classes, but I chose to use classes since intent is important and classes are better recognisable by tooling. (and by JSDoc which is relevant for #1218)

The benchmark results are pretty strong: geomean is like a 4-5% speedup on my machine, and all benchmarks got faster, yet!

These are the biggest changes (ran with hyperfine, warmup = 5, N ≥ 10, inputs from the config_js.txt file), everything else is negligible as per the Welch t-test (using mean, stddev & number of runs; the tests where hyperfine complained about outliers are deemed as not significant):

Benchmark main after #1330 this PR Δ
mandelbrot 177 ms 108 ms −38.8%
sieve 150 ms 134 ms −10.6%
bounce 120 ms 114 ms −5.2%
storage 690 ms 672 ms −2.5%
product_early 248 ms 241 ms −2.7%
triples 375 ms 366 ms −2.4%
dyck_one 404 ms 385 ms −4.8%
number_matrix 357 ms 344 ms −3.7%
financial_format 294 ms 284 ms −3.4%

@jiribenes jiribenes changed the title Experiment: Change Ref and Arena from closures to classes in JS runtime Experiment: use classes for Ref and Arena instead of closures on JS Mar 21, 2026
@jiribenes jiribenes added the experiment Experimental branch, do not merge! label Mar 21, 2026

const TOPLEVEL_K = (x, ks) => { throw { computationIsDone: true, result: x } }
const TOPLEVEL_KS = { prompt: 0, arena: Arena(), rest: null }
const TOPLEVEL_KS = { stack: null, prompt: 0, arena: new Arena(), rest: null }
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Explicitly setting stack: null seems to help V8 so that it knows it's always the same "type".
Same for the one created in RESET.

@jiribenes jiribenes changed the title Experiment: use classes for Ref and Arena instead of closures on JS JS runtime: Use classes for Ref and Arena instead of closures Mar 23, 2026
@jiribenes jiribenes removed the experiment Experimental branch, do not merge! label Mar 23, 2026
@jiribenes jiribenes marked this pull request as ready for review March 23, 2026 13:43
@jiribenes
Copy link
Copy Markdown
Contributor Author

I think this is largely uncontroversial, so I'll merge this -- we can always revert later before the release if the Effekt Plots decide to go into an undesirable direction.

@jiribenes jiribenes merged commit 8542a18 into main Mar 23, 2026
7 checks passed
@jiribenes jiribenes deleted the experiment/js/arena-as-a-class branch March 23, 2026 14:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant