Inside dispatcher logic in ConnectionManager, I noticed an opportunity to eliminate unnecessary atomic operations on the hot path.
Currently, dispatch_account_update, dispatch_transaction_update, and dispatch_slot_update iterate over self.connections using slot.load_full():
code
for (idx, slot) in self.connections.iter().enumerate() {
let Some(entry) = slot.load_full() else {
continue;
};
// ...
}
Bottleneck:
load_full() performs an atomic increment/decrement on the underlying Arc's reference count. On a high-throughput Solana stream (e.g., 50k+ updates/sec), doing this for every slot on every update causes significant cache-line bouncing and memory bus contention.
Proposed Solution:
Switch the hot-path iteration to use slot.load() instead, which returns a Guard.
for (idx, slot) in self.connections.iter().enumerate() {
let guard = slot.load();
let Some(entry) = guard.as_deref() else {
continue;
};
// ...
}
Because the Guard is scoped to the loop iteration and dropped immediately, it utilizes arc-swap's thread-local hazard pointers (staying well under the cheap proxy limit) and avoids the atomic reference count bump. We can pass &ManagedConnection to the helper functions down the stack.
I'd love to contribute this fix. Let me know if you're open to a PR!
Inside dispatcher logic in
ConnectionManager, I noticed an opportunity to eliminate unnecessary atomic operations on the hot path.Currently,
dispatch_account_update,dispatch_transaction_update, anddispatch_slot_updateiterate overself.connectionsusingslot.load_full():code
Bottleneck:
load_full()performs an atomic increment/decrement on the underlyingArc's reference count. On a high-throughput Solana stream (e.g., 50k+ updates/sec), doing this for every slot on every update causes significant cache-line bouncing and memory bus contention.Proposed Solution:
Switch the hot-path iteration to use
slot.load()instead, which returns aGuard.Because the
Guardis scoped to the loop iteration and dropped immediately, it utilizesarc-swap's thread-local hazard pointers (staying well under the cheap proxy limit) and avoids the atomic reference count bump. We can pass&ManagedConnectionto the helper functions down the stack.I'd love to contribute this fix. Let me know if you're open to a PR!