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}