; Bench fixture (Bench iter): linked-list build + sum. ; ; Drives the heap allocator hard via a recursive Cons spine. Every ; ICons cell is one allocation (24 bytes: tag + Int payload + tail). ; A list of length N therefore costs N allocations. We invoke the ; workload at three different sizes within a single program run to ; cover small / medium / large territory. ; ; Both `cons_n` (build) and `sum_list` (traverse) are written in ; accumulator form so the recursive call sits in tail position and ; can be marked `tail-app`. This is essential at the sizes used here: ; without `musttail`, three million stack frames overflow the default ; thread stack and segfault. ; ; Workload sizes (hardcoded — AILang has no env-var/argv pipeline): ; ; 100_000 * 24 B = 2.4 MB ; 1_000_000 * 24 B = 24 MB ; 3_000_000 * 24 B = 72 MB ; ; (3M was chosen as the largest size that comfortably fits inside the ; bump allocator's 256 MB arena with headroom for closure pairs and ; misc allocations.) ; ; Build is allocation-heavy; sum is pure traversal of already-allocated ; heap (the interesting one for GC pressure / barrier overhead). ; ; Expected stdout (one int per line, the sum 0+1+...+(N-1) = N*(N-1)/2): ; 100_000 -> 4999950000 ; 1_000_000 -> 499999500000 ; 3_000_000 -> 4499998500000 (module bench_list_sum (data IntList (ctor INil) (ctor ICons (con Int) (con IntList))) (fn cons_n_acc (doc "Tail-recursive list builder. Result = accumulator-prepended list.") (type (fn-type (params (con Int) (con IntList)) (ret (con IntList)))) (params n acc) (body (if (app eq n 0) acc (tail-app cons_n_acc (app - n 1) (term-ctor IntList ICons (app - n 1) acc))))) (fn cons_n (doc "Build [0, 1, ..., n-1] :: IntList. Order doesn't matter for sum.") (type (fn-type (params (con Int)) (ret (con IntList)))) (params n) (body (app cons_n_acc n (term-ctor IntList INil)))) (fn sum_acc (doc "Tail-recursive sum.") (type (fn-type (params (con IntList) (con Int)) (ret (con Int)))) (params xs acc) (body (match xs (case (pat-ctor INil) acc) (case (pat-ctor ICons h t) (tail-app sum_acc t (app + acc h)))))) (fn sum_list (doc "Sum every element. Calls sum_acc with seed 0.") (type (fn-type (params (con IntList)) (ret (con Int)))) (params xs) (body (app sum_acc xs 0))) (fn run_one (doc "Build a list of length n, sum it, print the sum.") (type (fn-type (params (con Int)) (ret (con Unit)) (effects IO))) (params n) (body (app print (app sum_list (app cons_n n))))) (fn main (type (fn-type (params) (ret (con Unit)) (effects IO))) (params) (body (seq (app run_one 100000) (seq (app run_one 1000000) (app run_one 3000000))))))