diff --git a/plans/lua-on-sx.md b/plans/lua-on-sx.md index c1605c28..a7d1fcec 100644 --- a/plans/lua-on-sx.md +++ b/plans/lua-on-sx.md @@ -148,6 +148,28 @@ _Shared-file issues that need someone else to fix. Minimal repro only._ - _(none yet)_ +## Performance — sequence table representation (own code, fixable) + +**Root cause of the 7× timeout failures in the PUC-Rio suite (`sort.lua` and others).** + +Lua arrays are stored as string-keyed dicts: `{"1": v1, "2": v2, ...}`. Every array +read/write goes through `(get t (str i))` / `(dict-set! t (str i) v)` — one integer→string +coercion plus one dict operation per access. `table.sort` on 30k elements calls `lt?` and +`ts-swap` O(n log n) times; each comparison does ~4 dict-with-string-key ops. The JIT +compiles the sort lambdas but cannot eliminate the per-element string allocation overhead. + +**Fix:** Change the sequence portion of a Lua table from a string-keyed dict to a native SX +list (or an integer-keyed side array). Integer index reads/writes become `(list-ref arr i)` +/ `(list-set arr i v)` — no string coercion, O(1). Mixed tables (array part + hash part) +can keep a `{:seq [...] :hash {...}}` split and route accesses accordingly. + +**Files:** `lib/lua/runtime.sx` (table constructors, `lua-get`, `lua-set!`, `lua-len`, +`lua-table-sort`, iteration), `lib/lua/transpile.sx` (field/index access emit paths). + +**Expected impact:** sort.lua and other heavy-loop tests drop from timeout to sub-second. +The 7 timeout failures should become passes once integer indexing is O(1) with no string +allocation. + ## Known limitations (own code, not shared) - **`require` supports `package.preload` only** — no filesystem search (we don't have Lua-file resolution inside sx_server). Users register a loader in `package.preload.name` and `require("name")` calls it with name as arg. Results cached in `package.loaded`; nil return caches as `true` per Lua convention.