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:
parent
599c0468f7
commit
4a1a9e3aec
8 changed files with 78 additions and 12 deletions
|
|
@ -29,3 +29,16 @@
|
|||
["unrealized" "false" "(realized? (lazy-seq (cons 1 nil)))"]
|
||||
["realized after" "true" "(let [s (lazy-seq (cons 1 nil))] (first s) (realized? s))"]
|
||||
["body runs once" "1" "(let [c (atom 0) s (lazy-seq (do (swap! c inc) [1 2 3]))] (seq s) (seq s) @c)"])
|
||||
|
||||
# Independent walks over the SAME lazy seq share realization: each node's rest
|
||||
# wrapper is memoized (ls-rest-cached), so the shared rest-thunks run exactly
|
||||
# once. Pre-fix, every walk after the first re-ran the thunks — duplicating
|
||||
# side effects, and a doall'd seq of futures re-spawned them serially on the
|
||||
# deref walk (which is how it surfaced, via pmap).
|
||||
(defspec "lazy-seq / realization is shared across walks"
|
||||
["effects run once across three walks" "3"
|
||||
"(let [a (atom 0) s (map (fn [x] (swap! a inc) x) [1 2 3])] (doall s) (dorun s) (vec s) (deref a))"]
|
||||
["values stable across walks" "true"
|
||||
"(let [s (map inc [1 2 3])] (= (vec s) (vec s) [2 3 4]))"]
|
||||
["filter effects once" "4"
|
||||
"(let [a (atom 0) s (filter (fn [x] (swap! a inc) (odd? x)) [1 2 3 4])] (dorun s) (count s) (deref a))"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue