1use std::hint::{black_box, spin_loop};
2use std::thread;
3use std::time::Instant;
4
5use polymarket_kernel::calculate_quotes_logit;
6use polymarket_kernel::ring_buffer::{L2Update, SpscRingBuffer, split};
7
8const MARKETS: usize = 8_192;
9const QUOTE_ITERS: usize = 100_000;
10
11const SPSC_CAPACITY: usize = 1 << 20; const SPSC_MESSAGES: u64 = 10_000_000;
13
14fn bench_quote_latency() -> f64 {
15 let mut x_t = vec![0.0_f64; MARKETS];
16 let mut q_t = vec![0.0_f64; MARKETS];
17 let mut sigma_b = vec![0.0_f64; MARKETS];
18 let mut gamma = vec![0.0_f64; MARKETS];
19 let mut tau = vec![0.0_f64; MARKETS];
20 let mut k = vec![0.0_f64; MARKETS];
21
22 let mut bid_p = vec![0.0_f64; MARKETS];
23 let mut ask_p = vec![0.0_f64; MARKETS];
24
25 for i in 0..MARKETS {
26 let fi = i as f64;
27 x_t[i] = ((fi % 1000.0) / 1000.0 - 0.5) * 4.0; q_t[i] = (i as i64 % 41 - 20) as f64; sigma_b[i] = 0.10 + ((i % 200) as f64) * 0.0015; gamma[i] = 0.03 + ((i % 7) as f64) * 0.01; tau[i] = 0.05 + ((i % 365) as f64) / 365.0; k[i] = 1.0 + ((i % 50) as f64) * 0.08; }
34
35 for _ in 0..2_000 {
36 calculate_quotes_logit(
37 &x_t, &q_t, &sigma_b, &gamma, &tau, &k, &mut bid_p, &mut ask_p,
38 );
39 }
40
41 let start = Instant::now();
42 for _ in 0..QUOTE_ITERS {
43 calculate_quotes_logit(
44 black_box(&x_t),
45 black_box(&q_t),
46 black_box(&sigma_b),
47 black_box(&gamma),
48 black_box(&tau),
49 black_box(&k),
50 black_box(&mut bid_p),
51 black_box(&mut ask_p),
52 );
53 }
54 let elapsed = start.elapsed();
55
56 let total_updates = (MARKETS as u128) * (QUOTE_ITERS as u128);
57 let ns_per_market = elapsed.as_nanos() as f64 / total_updates as f64;
58
59 black_box((&bid_p, &ask_p));
60 ns_per_market
61}
62
63fn bench_spsc_throughput() -> f64 {
64 let mut ring = SpscRingBuffer::default();
65 let mut slots = vec![L2Update::default(); SPSC_CAPACITY];
66
67 let (mut producer, mut consumer) =
68 split(&mut ring, &mut slots).expect("failed to initialize SPSC ring buffer");
69
70 let start = Instant::now();
71
72 thread::scope(|scope| {
73 let producer_handle = scope.spawn(move || {
74 for i in 0..SPSC_MESSAGES {
75 let mut msg = L2Update {
76 market_id: i & 0x1fff,
77 mid_price: 0.45 + ((i % 10_000) as f64) * 0.00001,
78 implied_vol: 0.08 + ((i % 1_000) as f64) * 0.0001,
79 };
80
81 loop {
82 match producer.try_push(msg) {
83 Ok(()) => break,
84 Err(m) => {
85 msg = m;
86 spin_loop();
87 }
88 }
89 }
90 }
91 });
92
93 let consumer_handle = scope.spawn(move || {
94 let mut received = 0_u64;
95 let mut checksum = 0.0_f64;
96
97 while received < SPSC_MESSAGES {
98 if let Some(msg) = consumer.try_pop() {
99 received += 1;
100 checksum += msg.mid_price + msg.implied_vol + (msg.market_id as f64) * 1e-12;
101 } else {
102 spin_loop();
103 }
104 }
105
106 black_box(checksum);
107 received
108 });
109
110 producer_handle
111 .join()
112 .expect("producer thread panicked during benchmark");
113
114 let received = consumer_handle
115 .join()
116 .expect("consumer thread panicked during benchmark");
117 assert_eq!(received, SPSC_MESSAGES, "message loss in SPSC benchmark");
118 });
119
120 let elapsed = start.elapsed();
121 let secs = elapsed.as_secs_f64();
122 (SPSC_MESSAGES as f64 / 1_000_000.0) / secs
123}
124
125fn main() {
126 println!("============================================================");
127 println!(" POLYMARKET-KERNEL RAW BENCHMARK ");
128 println!("============================================================");
129 println!(" Quote Batch Size : {:>10} markets", MARKETS);
130 println!(" Quote Iterations : {:>10}", QUOTE_ITERS);
131
132 let ns_per_market = bench_quote_latency();
133 println!(
134 " Runtime-Dispatch Quote : {:>10.2} ns/market",
135 ns_per_market
136 );
137
138 println!("------------------------------------------------------------");
139 println!(" SPSC Ring Capacity : {:>10}", SPSC_CAPACITY);
140 println!(" SPSC Messages : {:>10}", SPSC_MESSAGES);
141
142 let mops = bench_spsc_throughput();
143 println!(" SPSC Throughput : {:>10.2} M msgs/sec", mops);
144 println!("============================================================");
145}