#include #include #include #include #include "vere/pkg/c3/defs.h" #include "vere/pkg/noun/allocate.h" #include "vere/pkg/noun/manage.h" #include "vere/pkg/noun/serial.h" #include "vere/pkg/noun/v3/allocate.h" // Timing utilities static double get_time() { struct timeval tv; gettimeofday(&tv, NULL); return tv.tv_sec + tv.tv_usec / 1000000.0; } // Benchmark a function static void benchmark(const char* name, int iterations, void (*f)(void)) { // Warmup int warmup = iterations / 10; if (warmup > 100) warmup = 100; for (int i = 0; i < warmup; i++) { f(); } // Actual benchmark double start = get_time(); for (int i = 0; i < iterations; i++) { f(); } double elapsed = get_time() - start; double avg = elapsed / iterations; printf("%-40s %d iters: avg=%.6f total=%.6f\n", name, iterations, avg, elapsed); } // Global variables for benchmarks static u3_noun test_atom_small; static u3_noun test_atom_large; static u3_noun test_cell; static u3_noun test_tree; static c3_y* jam_small_bytes; static c3_d jam_small_len; static c3_y* jam_tree_bytes; static c3_d jam_tree_len; // Benchmark functions static void bench_jam_cue_small() { c3_d len; c3_y* bytes; u3s_jam_xeno(test_atom_small, &len, &bytes); u3_noun result = u3s_cue_xeno(len, bytes); free(bytes); u3z(result); } static void bench_jam_cue_large() { c3_d len; c3_y* bytes; u3s_jam_xeno(test_atom_large, &len, &bytes); u3_noun result = u3s_cue_xeno(len, bytes); free(bytes); u3z(result); } static void bench_jam_cue_cell() { c3_d len; c3_y* bytes; u3s_jam_xeno(test_cell, &len, &bytes); u3_noun result = u3s_cue_xeno(len, bytes); free(bytes); u3z(result); } static void bench_jam_cue_tree() { c3_d len; c3_y* bytes; u3s_jam_xeno(test_tree, &len, &bytes); u3_noun result = u3s_cue_xeno(len, bytes); free(bytes); u3z(result); } static void bench_jam_only_small() { c3_d len; c3_y* bytes; u3s_jam_xeno(test_atom_small, &len, &bytes); free(bytes); } static void bench_cue_only_small() { u3_noun result = u3s_cue_xeno(jam_small_len, jam_small_bytes); u3z(result); } static void bench_jam_only_tree() { c3_d len; c3_y* bytes; u3s_jam_xeno(test_tree, &len, &bytes); free(bytes); } static void bench_cue_only_tree() { u3_noun result = u3s_cue_xeno(jam_tree_len, jam_tree_bytes); u3z(result); } int main(int argc, char* argv[]) { // Initialize urbit runtime c3_w wor_w = 1 << 27; // 128MB u3m_boot_lite(wor_w); // Create test data test_atom_small = 42; test_atom_large = u3i_chubs(1, (c3_d[]){1ULL << 63}); test_cell = u3nc(1, 2); // Build balanced tree: [[1 2] [3 4]] [[5 6] [7 8]] test_tree = u3nc( u3nc(u3nc(1, 2), u3nc(3, 4)), u3nc(u3nc(5, 6), u3nc(7, 8)) ); // Pre-jam for cue-only benchmarks u3s_jam_xeno(test_atom_small, &jam_small_len, &jam_small_bytes); u3s_jam_xeno(test_tree, &jam_tree_len, &jam_tree_bytes); printf("========================================\n"); printf("Jam/Cue Serialization Benchmarks (C)\n"); printf("========================================\n\n"); printf("Round-trip benchmarks:\n"); benchmark("jam/cue small atom (42)", 100000, bench_jam_cue_small); benchmark("jam/cue large atom (2^63)", 10000, bench_jam_cue_large); benchmark("jam/cue simple cell [1 2]", 100000, bench_jam_cue_cell); benchmark("jam/cue balanced tree (depth 3)", 50000, bench_jam_cue_tree); printf("\nJam-only benchmarks:\n"); benchmark("jam only (small atom)", 100000, bench_jam_only_small); benchmark("jam only (balanced tree)", 50000, bench_jam_only_tree); printf("\nCue-only benchmarks:\n"); benchmark("cue only (small atom)", 100000, bench_cue_only_small); benchmark("cue only (balanced tree)", 50000, bench_cue_only_tree); printf("\n========================================\n"); // Cleanup free(jam_small_bytes); free(jam_tree_bytes); return 0; }