Skip to content

Commit 18c4217

Browse files
author
conditional-team
committed
hotpath: zero-alloc on_book_update — pre-allocated fixed buffers replace Vec allocations
1 parent bc4853a commit 18c4217

File tree

1 file changed

+24
-16
lines changed
  • crates/atomic-hotpath/src

1 file changed

+24
-16
lines changed

crates/atomic-hotpath/src/lib.rs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -115,10 +115,15 @@ extern "C" {
115115

116116
// ── Safe Rust wrapper ─────────────────────────────────────────
117117

118+
/// Max depth levels per side — must match C++ HP_MAX_LEVELS.
119+
const MAX_LEVELS: usize = 40;
120+
118121
/// High-performance MM engine backed by C++ hot path.
119122
/// All compute happens in ~100-500ns per tick.
120123
pub struct HotPathEngine {
121124
ptr: *mut HpEngineOpaque,
125+
bid_buf: [HpLevel; MAX_LEVELS],
126+
ask_buf: [HpLevel; MAX_LEVELS],
122127
}
123128

124129
// SAFETY: The C++ engine has no thread-local state and all
@@ -147,35 +152,38 @@ impl HotPathEngine {
147152
)
148153
};
149154
assert!(!ptr.is_null(), "Failed to create C++ hot-path engine");
150-
Self { ptr }
155+
Self {
156+
ptr,
157+
bid_buf: [HpLevel::default(); MAX_LEVELS],
158+
ask_buf: [HpLevel::default(); MAX_LEVELS],
159+
}
151160
}
152161

153162
/// Process an order book update. Returns MM commands.
154-
/// This is THE hot path — ~100-500ns.
163+
/// This is THE hot path — zero-alloc, ~100-500ns.
155164
pub fn on_book_update(
156165
&mut self,
157166
bids: &[Level],
158167
asks: &[Level],
159168
is_snapshot: bool,
160169
) -> HpResult {
161-
// Convert Level slices to HpLevel arrays (zero-copy if layout matches,
162-
// but Level has Price(i64)+Qty(u64) which is same as HpLevel)
163-
let hp_bids: Vec<HpLevel> = bids
164-
.iter()
165-
.map(|l| HpLevel { price: l.price.0, qty: l.qty.0 })
166-
.collect();
167-
let hp_asks: Vec<HpLevel> = asks
168-
.iter()
169-
.map(|l| HpLevel { price: l.price.0, qty: l.qty.0 })
170-
.collect();
170+
let bid_count = bids.len().min(MAX_LEVELS);
171+
let ask_count = asks.len().min(MAX_LEVELS);
172+
173+
for i in 0..bid_count {
174+
self.bid_buf[i] = HpLevel { price: bids[i].price.0, qty: bids[i].qty.0 };
175+
}
176+
for i in 0..ask_count {
177+
self.ask_buf[i] = HpLevel { price: asks[i].price.0, qty: asks[i].qty.0 };
178+
}
171179

172180
unsafe {
173181
hp_on_book_update(
174182
self.ptr,
175-
hp_bids.as_ptr(),
176-
hp_bids.len() as i32,
177-
hp_asks.as_ptr(),
178-
hp_asks.len() as i32,
183+
self.bid_buf.as_ptr(),
184+
bid_count as i32,
185+
self.ask_buf.as_ptr(),
186+
ask_count as i32,
179187
is_snapshot,
180188
)
181189
}

0 commit comments

Comments
 (0)