/// Nock benchmark - C implementation /// /// Benchmarks various Nock operations using the C reference interpreter #include #include #include #include "../vere/pkg/noun/noun.h" static double get_time_ms(void) { struct timeval tv; gettimeofday(&tv, NULL); return (tv.tv_sec * 1000.0) + (tv.tv_usec / 1000.0); } static void bench_nock(const char* name, u3_noun subject, u3_noun formula, c3_w iterations) { double start = get_time_ms(); for (c3_w i = 0; i < iterations; i++) { u3_noun result = u3n_nock_on(u3k(subject), u3k(formula)); u3z(result); } double end = get_time_ms(); double total = end - start; double per_iter = total / iterations; printf("%-30s %8u iterations in %10.2f ms (%10.6f ms/iter, %10.0f ops/sec)\n", name, iterations, total, per_iter, 1000.0 / per_iter); } int main(int argc, char* argv[]) { // Initialize Urbit memory system u3m_boot_lite(1 << 26); // 64MB loom printf("Nock Benchmark - C Implementation\n"); printf("==================================\n\n"); c3_w iterations = 1000000; // 1M iterations for fast ops c3_w slow_iters = 100000; // 100K for slower ops // Benchmark 0: slot lookup { u3_noun subject = u3nc(u3i_word(42), u3i_word(99)); u3_noun formula = u3nc(0, 2); // [0 2] - get head bench_nock("Opcode 0: slot/fragment", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark 1: constant { u3_noun subject = u3i_word(0); u3_noun formula = u3nc(1, u3i_word(42)); // [1 42] bench_nock("Opcode 1: constant", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark 3: is-cell { u3_noun subject = u3i_word(0); u3_noun formula = u3nc(3, u3nc(1, u3i_word(42))); // [3 [1 42]] bench_nock("Opcode 3: is-cell (atom)", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark 4: increment { u3_noun subject = u3i_word(0); u3_noun formula = u3nc(4, u3nc(1, u3i_word(1000))); // [4 [1 1000]] bench_nock("Opcode 4: increment", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark 5: equality { u3_noun subject = u3i_word(0); u3_noun formula = u3nt(5, u3nc(1, u3i_word(42)), u3nc(1, u3i_word(42))); bench_nock("Opcode 5: equality (equal)", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark 6: if-then-else { u3_noun subject = u3i_word(0); // [6 [1 0] [1 11] [1 22]] u3_noun formula = u3nq(6, u3nc(1, 0), u3nc(1, u3i_word(11)), u3nc(1, u3i_word(22))); bench_nock("Opcode 6: if-then-else", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark 7: composition { u3_noun subject = u3i_word(42); // [7 [1 99] [0 1]] u3_noun formula = u3nt(7, u3nc(1, u3i_word(99)), u3nc(0, 1)); bench_nock("Opcode 7: composition", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark 8: push { u3_noun subject = u3i_word(42); // [8 [1 99] [0 1]] u3_noun formula = u3nt(8, u3nc(1, u3i_word(99)), u3nc(0, 1)); bench_nock("Opcode 8: push", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark: Fibonacci-like recursion (slower) { // Decrement: [6 [5 [0 1] [1 0]] [1 0] [8 [1 0] [4 [0 3]]]] // This is: if(subject == 0) 0 else subject-1 u3_noun dec_fol = u3nq(6, u3nt(5, u3nc(0, 1), u3nc(1, 0)), u3nc(1, 0), u3nt(8, u3nc(1, 0), u3nc(4, u3nc(0, 3)))); u3_noun subject = u3i_word(10); bench_nock("Complex: decrement loop", subject, dec_fol, slow_iters); u3z(subject); u3z(dec_fol); } // Benchmark: Tree construction { u3_noun subject = u3i_word(0); // [[1 1] [1 2]] - constructs a cell u3_noun formula = u3nc(u3nc(1, 1), u3nc(1, 2)); bench_nock("Cell construction", subject, formula, iterations); u3z(subject); u3z(formula); } // Benchmark: Deep slot lookup { // Build a deep tree: [[[[1 2] 3] 4] 5] u3_noun subject = u3nc(u3nc(u3nc(u3nc(1, 2), 3), 4), 5); u3_noun formula = u3nc(0, 16); // slot 16 = deepest left (1) bench_nock("Deep slot lookup (depth 4)", subject, formula, iterations); u3z(subject); u3z(formula); } printf("\n"); // Cleanup u3m_grab(u3_none); return 0; }