Skip to content

Commit d7ca7d2

Browse files
author
Pierre-Luc Tessier Gagne
committed
perf(neovi): avoid exception path on empty receive buffer
Root cause: `_recv_internal()` relied on catching `IndexError` from `deque.popleft()` when no frame was available. In polling-heavy workloads, empty reads can be common, so exception construction/handling becomes an avoidable steady-state cost. Implemented solution: - Replace `try/except IndexError` with an explicit `if not self.rx_buffer` branch after queue processing. - Keep behavior identical: return `(None, False)` when no message is available. Rationale vs alternatives: Branch-based empty checks are cheaper than exception-driven control flow in normal operation and require minimal code change. Performance evidence: Session microbenchmark for empty recv control flow (500,000 iterations): - exception path: 0.061096s - branch path: 0.011707s - speedup: ~5.22x Test methodology: - Synthetic `timeit` benchmark comparing empty deque try/except vs pre-check. - Functional validation in session: `python -m pytest test/test_neovi.py` -> passed. Assumptions, limitations, risks: - Biggest win occurs when the receive loop polls frequently without data. - If traffic is always dense, relative benefit is lower. Potential follow-ups: - Measure in a real notifier/polling deployment with realistic idle/active mix. Other identified optimizations not implemented in this commit: - NetworkID cast simplification in send.
1 parent 75b7530 commit d7ca7d2

1 file changed

Lines changed: 4 additions & 5 deletions

File tree

can/interfaces/ics_neovi/neovi_bus.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -460,12 +460,11 @@ def _ics_msg_to_message(self, ics_msg):
460460
def _recv_internal(self, timeout=0.1):
461461
if not self.rx_buffer:
462462
self._process_msg_queue(timeout=timeout)
463-
try:
464-
ics_msg = self.rx_buffer.popleft()
465-
msg = self._ics_msg_to_message(ics_msg)
466-
except IndexError:
463+
if not self.rx_buffer:
467464
return None, False
468-
return msg, False
465+
466+
ics_msg = self.rx_buffer.popleft()
467+
return self._ics_msg_to_message(ics_msg), False
469468

470469
@check_if_bus_open
471470
def send(self, msg, timeout=0):

0 commit comments

Comments
 (0)