ac70011352
The latency_harness.py harness spawns the bench binary on a PTY, records monotonic_ns() per stdout line, and reports inter-arrival gap distribution (median / p99 / p99.9 / max). Tail latency is Decision 10's central real-time claim; total wall-time and RSS are the wrong metrics for that question. Paired fixtures: bench_latency_implicit (Boehm-fair, no mode annotations, leaks under --alloc=rc) and bench_latency_explicit (mode-annotated hot path, what RC was built for). Both use a depth-19 balanced tree (~16 MB) as the persistent live working set, plus per-op IntList build+sum churn forcing GC pressure under Boehm. Authored by ailang-bencher; ships evidence, not features.
2 lines
8.2 KiB
JSON
2 lines
8.2 KiB
JSON
{"defs":[{"ctors":[{"fields":[],"name":"TLeaf"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"Tree"},{"k":"con","name":"Tree"}],"name":"TNode"}],"doc":"Balanced binary tree, 32-byte cells (tag + Int payload + 2 ptrs).","kind":"type","name":"Tree"},{"ctors":[{"fields":[],"name":"LNil"},{"fields":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"name":"LCons"}],"doc":"Singly-linked Int list, 24-byte cells.","kind":"type","name":"IntList"},{"body":{"cond":{"args":[{"name":"depth","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"lit":{"kind":"int","value":1},"t":"lit"},{"args":[{"args":[{"name":"depth","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build_tree","t":"var"},"t":"app"},{"args":[{"args":[{"name":"depth","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"}],"fn":{"name":"build_tree","t":"var"},"t":"app"}],"ctor":"TNode","t":"ctor","type":"Tree"},"t":"if","then":{"args":[],"ctor":"TLeaf","t":"ctor","type":"Tree"}},"doc":"Build a balanced tree of given depth, every value = 1. Constructor-blocked — recursion depth = `depth`, fits 8MB stack at depth 19.","kind":"fn","name":"build_tree","params":["depth"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Tree"}}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"TLeaf","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"v","t":"var"},{"args":[{"args":[{"name":"l","t":"var"}],"fn":{"name":"sum_tree","t":"var"},"t":"app"},{"args":[{"name":"r","t":"var"}],"fn":{"name":"sum_tree","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"pat":{"ctor":"TNode","fields":[{"name":"v","p":"var"},{"name":"l","p":"var"},{"name":"r","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"t","t":"var"},"t":"match"},"doc":"Touch every node of the tree (ensures liveness across the loop).","kind":"fn","name":"sum_tree","params":["t"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Int"}}},{"body":{"cond":{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"args":[{"name":"n","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"name":"acc","t":"var"}],"ctor":"LCons","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app","tail":true},"t":"if","then":{"name":"acc","t":"var"}},"doc":"Tail-recursive list builder. Result = [n-1, n-2, ..., 0] :: IntList.","kind":"fn","name":"cons_n_acc","params":["n","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"IntList"}}},{"body":{"args":[{"name":"n","t":"var"},{"args":[],"ctor":"LNil","t":"ctor","type":"IntList"}],"fn":{"name":"cons_n_acc","t":"var"},"t":"app"},"doc":"Build [0,1,...,n-1] :: IntList.","kind":"fn","name":"cons_n","params":["n"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"}],"ret":{"k":"con","name":"IntList"}}},{"body":{"arms":[{"body":{"name":"acc","t":"var"},"pat":{"ctor":"LNil","fields":[],"p":"ctor"}},{"body":{"args":[{"name":"t","t":"var"},{"args":[{"name":"acc","t":"var"},{"name":"h","t":"var"}],"fn":{"name":"+","t":"var"},"t":"app"}],"fn":{"name":"sum_list_acc","t":"var"},"t":"app","tail":true},"pat":{"ctor":"LCons","fields":[{"name":"h","p":"var"},{"name":"t","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"xs","t":"var"},"t":"match"},"doc":"Tail-recursive sum.","kind":"fn","name":"sum_list_acc","params":["xs","acc"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"IntList"},{"k":"con","name":"Int"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"name":"xs","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"sum_list_acc","t":"var"},"t":"app"},"doc":"Sum every element. Calls sum_list_acc with seed 0.","kind":"fn","name":"sum_list","params":["xs"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"IntList"}],"ret":{"k":"con","name":"Int"}}},{"body":{"arms":[{"body":{"lit":{"kind":"int","value":0},"t":"lit"},"pat":{"ctor":"TLeaf","fields":[],"p":"ctor"}},{"body":{"lit":{"kind":"int","value":1},"t":"lit"},"pat":{"ctor":"TNode","fields":[{"name":"v","p":"var"},{"name":"l","p":"var"},{"name":"r","p":"var"}],"p":"ctor"}}],"scrutinee":{"name":"t","t":"var"},"t":"match"},"doc":"Constant-time tree liveness pin — read root tag, return 1 (TNode) or 0 (TLeaf).","kind":"fn","name":"pin_root","params":["t"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Int"}}},{"body":{"args":[{"args":[{"args":[{"name":"chunk_len","t":"var"}],"fn":{"name":"cons_n","t":"var"},"t":"app"}],"fn":{"name":"sum_list","t":"var"},"t":"app"},{"args":[{"name":"t","t":"var"}],"fn":{"name":"pin_root","t":"var"},"t":"app"}],"fn":{"name":"+","t":"var"},"t":"app"},"doc":"One bench operation: build+sum a fresh CHUNK_LEN-cell list, pin the tree's root, return their sum so the value chain stays observable.","kind":"fn","name":"one_op","params":["chunk_len","t"],"type":{"effects":[],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Int"}}},{"body":{"cond":{"args":[{"name":"remaining","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"cond":{"args":[{"name":"print_countdown","t":"var"},{"lit":{"kind":"int","value":0},"t":"lit"}],"fn":{"name":"==","t":"var"},"t":"app"},"else":{"body":{"args":[{"args":[{"name":"remaining","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"name":"print_countdown","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"name":"chunk_len","t":"var"},{"name":"print_k","t":"var"},{"name":"t","t":"var"}],"fn":{"name":"loop","t":"var"},"t":"app","tail":true},"name":"_v","t":"let","value":{"args":[{"name":"chunk_len","t":"var"},{"name":"t","t":"var"}],"fn":{"name":"one_op","t":"var"},"t":"app"}},"t":"if","then":{"lhs":{"args":[{"args":[{"name":"chunk_len","t":"var"},{"name":"t","t":"var"}],"fn":{"name":"one_op","t":"var"},"t":"app"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"args":[{"name":"remaining","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"args":[{"name":"print_k","t":"var"},{"lit":{"kind":"int","value":1},"t":"lit"}],"fn":{"name":"-","t":"var"},"t":"app"},{"name":"chunk_len","t":"var"},{"name":"print_k","t":"var"},{"name":"t","t":"var"}],"fn":{"name":"loop","t":"var"},"t":"app","tail":true},"t":"seq"}},"t":"if","then":{"args":[{"lit":{"kind":"int","value":9999},"t":"lit"}],"op":"io/print_int","t":"do"}},"doc":"Tail-recursive bench loop. Ops countdown in `remaining`; print marker every time `print_countdown` hits 0.","kind":"fn","name":"loop","params":["remaining","print_countdown","chunk_len","print_k","t"],"type":{"effects":["IO"],"k":"fn","params":[{"k":"con","name":"Int"},{"k":"con","name":"Int"},{"k":"con","name":"Int"},{"k":"con","name":"Int"},{"k":"con","name":"Tree"}],"ret":{"k":"con","name":"Unit"}}},{"body":{"body":{"body":{"lhs":{"args":[{"lit":{"kind":"int","value":8888},"t":"lit"}],"op":"io/print_int","t":"do"},"rhs":{"args":[{"lit":{"kind":"int","value":20000},"t":"lit"},{"lit":{"kind":"int","value":0},"t":"lit"},{"lit":{"kind":"int","value":500},"t":"lit"},{"lit":{"kind":"int","value":20},"t":"lit"},{"name":"t","t":"var"}],"fn":{"name":"loop","t":"var"},"t":"app"},"t":"seq"},"name":"_root","t":"let","value":{"args":[{"name":"t","t":"var"}],"fn":{"name":"pin_root","t":"var"},"t":"app"}},"name":"t","t":"let","value":{"args":[{"lit":{"kind":"int","value":19},"t":"lit"}],"fn":{"name":"build_tree","t":"var"},"t":"app"}},"doc":"Top-level: build tree, signal READY (8888), run loop, signal DONE (9999 emitted by loop).","kind":"fn","name":"main","params":[],"type":{"effects":["IO"],"k":"fn","params":[],"ret":{"k":"con","name":"Unit"}}}],"imports":[],"name":"bench_latency_implicit","schema":"ailang/v0"}
|