; Bench fixture: pure-compute integer loop, no heap. ; ; Tail-recursive accumulator loop. Each step does one multiply and one ; add; no heap allocation, no closure capture, no pattern matching. ; The point is to isolate codegen quality on tight integer loops: ; under all three allocators the wall-time should be essentially ; identical (no allocator pressure to differentiate them), so any ; observed gc/bump/rc delta on this fixture is signal about codegen, ; not about memory management. ; ; Workload: intsum_loop(n, 0) with n iterations, each contributing ; i * 7 to the accumulator. ; ; Closed form: sum_{i=1..N} i * 7 = 7 * N * (N+1) / 2 ; N = 1_000_000 -> 3_500_003_500_000 ; N = 10_000_000 -> 350_000_035_000_000 ; N = 50_000_000 -> 8_750_000_175_000_000 ; ; All three results fit comfortably in i64 (max 9.22e18). (module bench_compute_intsum (fn intsum_loop (doc "Tail-recursive: acc += i*7 for i in [n, n-1, ..., 1]. Returns final acc.") (type (fn-type (params (own (con Int)) (own (con Int))) (ret (own (con Int))))) (params i acc) (body (if (app eq i 0) acc (tail-app intsum_loop (app - i 1) (app + acc (app * i 7)))))) (fn run_one (type (fn-type (params (own (con Int))) (ret (own (con Unit))) (effects IO))) (params n) (body (app print (app intsum_loop n 0)))) (fn main (type (fn-type (params) (ret (own (con Unit))) (effects IO))) (params) (body (seq (app run_one 1000000) (seq (app run_one 10000000) (app run_one 50000000))))))