Skip to content

Commit 9fb3e5f

Browse files
author
MesTTo
committed
docs(bench): record optimization log + post-pass numbers (oracle 62->39ms, fib 35% faster)
1 parent 67d186e commit 9fb3e5f

1 file changed

Lines changed: 21 additions & 12 deletions

File tree

packages/node/bench/RESULTS.md

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,28 @@
11
# Benchmark results
22

33
Pure TypeScript, no native addon, no WASM. Node v22, single core.
4-
Run: `pnpm --filter @metta-ts/core build && node packages/node/bench/suite.mjs` (deopt-aware mitata).
4+
Run: `pnpm bench` (builds core, then deopt-aware mitata).
55

6-
## Hot paths (mitata)
6+
## Hot paths (mitata, after the Phase-15 optimization pass)
77

8-
| benchmark | time/iter | notes |
9-
|-----------|-----------|-------|
10-
| `matchAtoms` symbol mismatch | ~10 ns | the fast-reject path |
11-
| `matchAtoms` nested, binds 2 vars | ~212 ns | 21× the mismatch cost |
12-
| `match` over a 1000-atom space | ~321 µs | linear scan (Phase-15 index targets this) |
13-
| `fib(15)` (~1.2k recursive calls) | ~27 ms | tree-walker, no memoization |
14-
| stdlib load + `(+ 1 2)` | ~13 µs | prelude atoms cached |
15-
| full 270-assertion Hyperon oracle | ~62 ms | all 22 files, `buildEnv` per query |
8+
| benchmark | time/iter |
9+
|-----------|-----------|
10+
| `matchAtoms` symbol mismatch | ~9 ns |
11+
| `matchAtoms` nested, binds 2 vars | ~222 ns |
12+
| `match` over a 1000-atom space | ~201 µs |
13+
| `fib(15)` (~1.2k recursive calls) | ~17 ms |
14+
| stdlib load + `(+ 1 2)` | ~12 µs |
15+
| full 270-assertion Hyperon oracle | ~39 ms |
1616

17-
## Reading these
17+
## Optimization log (profile-driven, each gated by the 270/270 oracle)
1818

19-
Correctness-first numbers from a faithful tree-walker. The clear hot spots — per-query `buildEnv`, the linear space scan, and the `mettaEval` allocation in `fib` — are exactly what the Phase-15 roadmap targets (staging/partial-evaluation, a flat interned atom core, a bytecode VM, a `mnemonist` AtomSpace index). Every optimization is gated by the 270/270 oracle so speed never costs correctness, and must show a before/after number here.
19+
Method: `node --prof` to find hot spots, research the V8/interpreter technique, apply, re-measure, keep only if the oracle stays 270/270. Inspiration drawn from tau-prolog (a mature JS Prolog interpreter) and MORK (interned/flat representation, avoid allocation).
20+
21+
1. **Incremental env build** — extend `MinEnv` per atom instead of rebuilding it on every query.
22+
2. **State/token short-circuit**`subTokens`/`resolveStates`/`wrapStates` return the atom unchanged when the world has no tokens/states (skips a full tree clone on every grounded-op eval). Oracle 62 → 47 ms.
23+
3. **`applySubst` structural sharing** — skip empty substitutions and return the same reference when a subtree is unchanged (no clone). `fib`~25%.
24+
4. **Precomputed `ground` flag** (tau-prolog's `Term.apply`: `if (this.ground) return this`) — `applySubst`/`atomVars`/`occurs` short-circuit instantly on closed terms; plus shared constant leaf type-arrays in `getTypes`. Oracle → ~39 ms; 1000-atom match 321 → 201 µs; `fib(15)` 26.6 → 17.4 ms.
25+
26+
Net: the full oracle went from ~62 ms to ~39 ms (~37% faster) and `fib(15)` from ~26.6 ms to ~17.4 ms (~35% faster), correctness unchanged at 270/270.
27+
28+
The deeper Phase-15 levers (staging/partial-evaluation, a MORK-style flat interned atom core, a bytecode VM, a `mnemonist` AtomSpace index) remain as the next round, same profile→research→measure→gate loop.

0 commit comments

Comments
 (0)