; Bench fixture (Bench iter): balanced-tree build + sum. ; ; Allocates a balanced binary tree of `Node value left right` cells, ; then walks it summing the value field. Distinct from ; `bench_list_sum` in two ways: ; 1. Each tree node has an additional pointer field versus a list ; cell — 32-byte alloc instead of 24-byte. The branching shape ; means the recursion structure is genuinely tree-shaped: the ; build cannot be made tail-recursive without explicit ; continuation passing, so this fixture is constrained to depths ; where the recursion stack fits. ; 2. The traversal pattern hits two children per node, exercising ; the GC's mark-phase pointer-chasing heuristics differently from ; a plain linked-list walk. ; ; Depth picked: 20 -> 2^20 - 1 = 1_048_575 nodes -> 32 MB heap usage. ; Recursion depth in `build_tree` and `sum_tree` matches `depth`, ; which fits comfortably in the default 8 MB system stack. ; ; Hardcoded multi-call form: build/sum the same tree thrice for ; signal averaging. The depths are different per call so the GC has ; to deal with three independent live-set sizes. ; ; Expected stdout (one int per line): ; depth 16: 2^16 - 1 = 65535 nodes, sum = 65535 ; depth 18: 2^18 - 1 = 262143 nodes, sum = 262143 ; depth 20: 2^20 - 1 = 1048575 nodes, sum = 1048575 ; ; (Each node stores literal `1`; sum is therefore node count.) (module bench_tree_walk (data Tree (ctor Leaf) (ctor Node (con Int) (con Tree) (con Tree))) (fn build_tree (doc "Balanced binary tree of given depth, every value = 1.") (type (fn-type (params (con Int)) (ret (con Tree)))) (params depth) (body (if (app == depth 0) (term-ctor Tree Leaf) (term-ctor Tree Node 1 (app build_tree (app - depth 1)) (app build_tree (app - depth 1)))))) (fn sum_tree (doc "Sum every Node value via match recursion. Constructor-blocked: not tail-recursive, but recursion depth = tree depth so fits.") (type (fn-type (params (con Tree)) (ret (con Int)))) (params t) (body (match t (case (pat-ctor Leaf) 0) (case (pat-ctor Node v l r) (app + v (app + (app sum_tree l) (app sum_tree r))))))) (fn run_one (doc "Build a tree of given depth, sum it, print the sum.") (type (fn-type (params (con Int)) (ret (con Unit)) (effects IO))) (params depth) (body (do io/print_int (app sum_tree (app build_tree depth))))) (fn main (type (fn-type (params) (ret (con Unit)) (effects IO))) (params) (body (seq (app run_one 16) (seq (app run_one 18) (app run_one 20))))))