Skip to content

Commit

Permalink
Avoid a dict lookup to process every packet
Browse files Browse the repository at this point in the history
  • Loading branch information
bdraco committed Sep 3, 2024
1 parent 7e7ece4 commit 8e6673e
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 2 deletions.
4 changes: 3 additions & 1 deletion aioesphomeapi/connection.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ cpdef void handle_complex_message(
cdef object _handle_timeout
cdef object _handle_complex_message

cdef tuple MESSAGE_NUMBER_TO_PROTO


@cython.dataclasses.dataclass
cdef class ConnectionParams:
Expand Down Expand Up @@ -119,7 +121,7 @@ cdef class APIConnection:
cdef void send_messages(self, tuple messages)

@cython.locals(handlers=set, handlers_copy=set)
cpdef void process_packet(self, object msg_type_proto, object data)
cpdef void process_packet(self, unsigned int msg_type_proto, object data)

cdef void _async_cancel_pong_timer(self)

Expand Down
7 changes: 6 additions & 1 deletion aioesphomeapi/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@

_LOGGER = logging.getLogger(__name__)

MESSAGE_NUMBER_TO_PROTO = tuple(MESSAGE_TYPE_TO_PROTO.values())


PREFERRED_BUFFER_SIZE = 2097152 # Set buffer limit to 2MB
MIN_BUFFER_SIZE = 131072 # Minimum buffer size to use

Expand Down Expand Up @@ -888,7 +891,9 @@ def _set_fatal_exception_if_unset(self, err: Exception) -> None:
def process_packet(self, msg_type_proto: _int, data: _bytes) -> None:
"""Process an incoming packet."""
debug_enabled = self._debug_enabled
if (klass := MESSAGE_TYPE_TO_PROTO.get(msg_type_proto)) is None:
try:
klass = MESSAGE_NUMBER_TO_PROTO[msg_type_proto + 1]
except IndexError:
if debug_enabled:
_LOGGER.debug(
"%s: Skipping unknown message type %s",
Expand Down
2 changes: 2 additions & 0 deletions aioesphomeapi/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,3 +393,5 @@ def __init__(self, error: BluetoothGATTError) -> None:
117: UpdateStateResponse,
118: UpdateCommandRequest,
}

MESSAGE_NUMBER_TO_PROTO = tuple(MESSAGE_TYPE_TO_PROTO.values())
9 changes: 9 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
from __future__ import annotations

from aioesphomeapi.core import MESSAGE_TYPE_TO_PROTO


def test_order_and_no_missing_numbers_in_message_type_to_proto():
"""Test that MESSAGE_TYPE_TO_PROTO has no missing numbers."""
for idx, (k, v) in enumerate(MESSAGE_TYPE_TO_PROTO.items()):
assert idx + 1 == k

0 comments on commit 8e6673e

Please sign in to comment.