code wiki / (root) / nx_bench_hll_vs_cpc.nx

nx_bench_hll_vs_cpc.nx source

↩ module page · 85 lines · 3032 B

1// bench_hll_vs_cpc.nx -- head-to-head workload runner. 2// 3// Streams N distinct synthetic keys through OUR HLL_8 and OUR CPC at 4// matched lg_k, then feeds estimates + memory into the comparator 5// for a sealed verdict. 6// 7// This is sister-comparison (our vs our), validating Lang 2017's HIP 8// claim that CPC beats HLL on accuracy at same memory. The harness 9// extends naturally: swap CPC for a Python-datasketches stub to compare 10// against the incumbent. 11 12// nx_safety_envelope: 13// intended_use: AUTO_APPLIED -- primitive-specific tuning queued 14// sil_target: SIL1 15// evidence: [bulk_applied_2026-05-16, see-file-comment-for-detail] 16// verdict: NOT_YET_EVALUATED 17 18import "nx_syscalls.nx" 19import "nx_sketch_hll.nx" 20import "nx_sketch_cpc.nx" 21import "nx_sketch_comparator.nx" 22import "nx_sketch_types.nx" 23const K_MAGIC_8192: i64 = 8192 24const K_MAGIC_10000: i64 = 10000 25 26func main() -> i64 { 27 let lg_k: i64 = 7 // m = 128 for both 28 let n: i64 = 1000 // distinct keys 29 30 let hll: *Hll = nx_hll_alloc(lg_k, 42) 31 let cpc: *Cpc = nx_cpc_alloc(lg_k, K_MAGIC_8192, 42) 32 if hll == (0 as *Hll) { return __syscall(93, 5, 0, 0, 0, 0, 0) } 33 if cpc == (0 as *Cpc) { return __syscall(93, 6, 0, 0, 0, 0, 0) } 34 35 // Stream N distinct 8-byte keys through both. 36 let buf: *u8 = sys_mmap(8) 37 var i: i64 = 0 38 while i < n { 39 buf[0] = (i ) & 0xFF 40 buf[1] = (i >> 8 ) & 0xFF 41 buf[2] = (i >> 16) & 0xFF 42 buf[3] = 0xA1 43 buf[4] = 0 44 buf[5] = 0 45 buf[6] = 0 46 buf[7] = 0 47 nx_hll_add(hll, buf, 8) 48 nx_cpc_add(cpc, buf, 8) 49 i = i + 1 50 } 51 52 let hll_est: i64 = nx_hll_estimate(hll) 53 let cpc_est: i64 = nx_cpc_estimate(cpc) 54 55 // --- ACCURACY: who's closer to truth = n ? --- 56 // "ours" = CPC (the claimed-better one); "theirs" = HLL (baseline) 57 let r_acc: *ComparisonResult = nx_cmp_accuracy(cpc_est, hll_est, n, K_MAGIC_10000) 58 59 // --- MEMORY: CPC vs HLL footprint --- 60 let cpc_mem: i64 = nx_cpc_memory_bytes(cpc) 61 let hll_mem: i64 = 24 + (1 << lg_k) // HLL header + register array 62 let r_mem: *ComparisonResult = nx_cmp_memory(cpc_mem, hll_mem, K_MAGIC_10000) 63 64 // --- TIME: skip (would need external wall-clock; report as EQUIV) --- 65 let r_tim: *ComparisonResult = nx_cmp_time(100, 100, K_MAGIC_10000) 66 67 // --- COMPOSITE verdict --- 68 let composite: i64 = nx_cmp_composite(r_acc, r_mem, r_tim) 69 70 // --- Encode results into i64 return for harness to parse --- 71 // Bits 0-3: accuracy verdict 72 // Bits 4-7: memory verdict 73 // Bits 8-11: time verdict 74 // Bits 12-15: composite 75 // Bits 16-31: hll_est (16-bit truncated) 76 // Bits 32-47: cpc_est (16-bit truncated) 77 var ret: i64 = 0 78 ret = ret | r_acc.verdict 79 ret = ret | (r_mem.verdict << 4) 80 ret = ret | (r_tim.verdict << 8) 81 ret = ret | (composite << 12) 82 ret = ret | ((hll_est & 0xFFFF) << 16) 83 ret = ret | ((cpc_est & 0xFFFF) << 32) 84 return ret 85}