Skip to content

Performance

The engine is built to run on every keystroke, which sets the performance bar.

Expressions compile to a compact bytecode and run on a stack machine. Compiling once and executing many times is much faster than re-walking a syntax tree, and it makes the execution step easy to bound.

Compiled bytecode is cached by expression text, so an unchanged line skips lexing, normalising, parsing and compiling entirely. Line results are cached separately, so an unchanged line skips execution too.

  1. Lex
  2. Normalise
  3. Parse
  4. Compile
  5. Execute

Every stage runs. This is the full cost, and it is paid once per distinct expression text.

Three layers

A dependency graph records which lines read which variables, so editing a line recomputes only what transitively depends on it.

Constructing a new engine per evaluation throws away every cache and re-registers every package. Create one engine and call clear() between documents.

Enabling diagnostics collects a large amount of per-stage detail. It is intended for a devtool and should be off in production.