core: lazy realization is shared across walks (once-only effects); pmap family

Every walk over a lazy seq created FRESH wrapper tables around the shared
rest-thunks (ls-rest, ls-seq/ls-count, realize-for-iteration, the printers,
reduce — each had its own make-lazy-seq loop), so independent walks re-ran
the thunks: side effects duplicated, and a doall'd seq of futures was
re-spawned serially by the deref walk. Every walker now goes through
ls-rest-cached, which memoizes the rest wrapper on its node — thunks run
exactly once, as in Clojure. Costs ~10% on walk-heavy benches (the per-node
cache get/put — Clojure's LazySeq pays the same); net still -9% vs the
pre-linear-walks baseline. Three regression rows pin once-only effects and
value stability across walks.

On top of that: pmap/pcalls/pvalues (jolt-oeu) over the real-thread futures
— spawn-all-then-deref (the once-only fix is what makes the doall actually
mean that), snapshot semantics documented, multi-coll arity via the
canonical vector-zip. System/currentTimeMillis + nanoTime land as System
statics (the realtime clock — os/time is whole seconds, which quantized
every elapsed measurement to 1000ms). Seven pmap rows incl. a generous-
margin parallelism check (4 x 200ms sleeps under 700ms after warmup).
This commit is contained in:
Yogthos 2026-06-10 19:14:45 -04:00
parent 599c0468f7
commit 4a1a9e3aec
8 changed files with 78 additions and 12 deletions

View file

@ -49,3 +49,16 @@
# The future's own return value still reflects the swap on its copy.
["future sees its own mutation"
"1" "(let [a (atom 0)] (deref (future (swap! a inc))))"])
# pmap/pcalls/pvalues over the real-thread futures: spawn-all-then-deref, so
# independent work overlaps; snapshot semantics (pure fns only). The wall-time
# row uses generous margins (4 x 150ms in parallel vs 600ms serial).
(defspec "clojure.core / pmap family"
["pmap values in order" "[2 3 4]" "(vec (pmap inc [1 2 3]))"]
["pmap multi-coll" "[5 7 9]" "(vec (pmap + [1 2 3] [4 5 6]))"]
["pmap empty" "()" "(pmap inc [])"]
["pmap is parallel" "true"
"(do (deref (future :warmup)) (let [t0 (System/currentTimeMillis)] (dorun (pmap (fn [_] (Thread/sleep 200)) [1 2 3 4])) (< (- (System/currentTimeMillis) t0) 700)))"]
["pcalls" "[1 2]" "(vec (pcalls (fn [] 1) (fn [] 2)))"]
["pvalues" "[3 7]" "(vec (pvalues (+ 1 2) (+ 3 4)))"]
["snapshot semantics" "0" "(let [a (atom 0)] (dorun (pmap (fn [_] (swap! a inc)) [1 2])) (deref a))"])