ad5d7389
lazy: SoA index layout (sparse-read 0.66× → 0.90×, passthrough 1.5× → 1.7×)
Replace per-segment Lua tables with four parallel integer arrays
(id, tag_start, val_start, next_start). For an emails-heavy Person at
100KB that's 4 tables of 2800 ints instead of 2800 tables of 4 keys —
~5× fewer table allocations on decode_lazy.
ArrayView and MapView are similarly flattened: each holds a single
int array of val_starts instead of one mini-table per element.
Packed-payload expansion produces the same shape so :at(i) is one
array index lookup + decode call.
Before / after on bench/lazy_bench.lua (1KB / 10KB / 100KB):
passthrough (decode + reencode)
full: 1.43× → 1.73× 1.13× → 1.62× 1.04× → 1.69×
runtime: 1.43× → 1.94× 1.15× → 1.73× 1.16× → 1.84×
sparse read (:get name + :get age)
full: 0.70× → 0.90× 0.65× → 0.94× 0.60× → 1.03×
runtime: 0.76× → 0.99× 0.66× → 1.05× 0.68× → 1.16×
rewrite name (decode + set + reencode)
full: 0.98× → 1.11× 0.82× → 1.09× 0.81× → 1.14×
runtime: 1.06× → 1.26× 0.95× → 1.15× 0.85× → 1.25×
Sparse read goes from a loss to break-even or better; passthrough
gain widens; mutate-then-reencode flips from regression to consistent
win. JIT-trace gate still 19/19 — the index loop's single side-trace
bridge (decode_tag at lazy.lua:49) was at decode_tag in the old code
too; same pattern, different line number.
Drops the unused wt field from the SoA: consumers never re-read the
tag wire type after the index pass. Unknown-field splice and lazy
:encode emit byte slices directly from tag_start..next_start.
Eugene Blikh <bigbes@gmail.com> — 2026-05-15 14:25:46 UTC
Commit ad5d73898eeaf88d40e97612141ebcedd6d8ed02 —
view raw patch
Parent(s):
1004cc60
| File | Status | + | − |
|---|---|---|---|
runtime/pb/lazy.lua
|
M | +173 | -209 |