feat: optimize passive bluez message unmarshaller (#216)

This commit is contained in:
J. Nick Koston 2023-08-02 05:36:53 -10:00 committed by GitHub
parent a7c87fb8fd
commit e0e87ec16c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 24 additions and 15 deletions

View File

@ -19,7 +19,6 @@ repos:
- id: debug-statements
- id: check-builtin-literals
- id: check-case-conflict
- id: check-docstring-first
- id: check-json
- id: check-toml
- id: check-xml

View File

@ -21,6 +21,7 @@ unmarshaller = Unmarshaller(stream)
def unmarhsall_bluez_rssi_message():
stream.seek(0)
unmarshaller.unmarshall()
unmarshaller.unmarshall()
count = 3000000

View File

@ -112,16 +112,18 @@ cdef class Unmarshaller:
cdef unsigned int _body_len
cdef unsigned int _serial
cdef unsigned int _header_len
cdef object _message_type
cdef object _flag
cdef unsigned int _message_type
cdef unsigned int _flag
cdef unsigned int _msg_len
cdef unsigned int _is_native
cdef object _uint32_unpack
cdef object _int16_unpack
cdef object _uint16_unpack
cdef object _stream_reader
cdef object _sock_reader
cdef bint _negotiate_unix_fd
cdef bint _read_complete
cdef unsigned int _endian
cdef _next_message(self)

View File

@ -202,8 +202,10 @@ class Unmarshaller:
"_uint16_unpack",
"_is_native",
"_stream_reader",
"_sock_reader",
"_negotiate_unix_fd",
"_read_complete",
"_endian",
)
def __init__(
@ -236,6 +238,11 @@ class Unmarshaller:
if isinstance(stream, io.BufferedRWPair) and hasattr(stream, "reader"):
self._stream_reader = stream.reader.read # type: ignore[attr-defined]
self._stream_reader = stream.read
elif self._negotiate_unix_fd:
self._sock_reader = self._sock.recvmsg
else:
self._sock_reader = self._sock.recv
self._endian = 0
def _next_message(self) -> None:
"""Reset the unmarshaller to its initial state.
@ -280,7 +287,7 @@ class Unmarshaller:
# This will raise BlockingIOError if there is no data to read
# which we store in the MARSHALL_STREAM_END_ERROR object
try:
recv = self._sock.recvmsg(missing_bytes, UNIX_FDS_CMSG_LENGTH) # type: ignore[union-attr]
recv = self._sock_reader(missing_bytes, UNIX_FDS_CMSG_LENGTH) # type: ignore[union-attr]
except OSError as e:
errno = e.errno
if errno == EAGAIN or errno == EWOULDBLOCK:
@ -311,7 +318,7 @@ class Unmarshaller:
# which we store in the MARSHALL_STREAM_END_ERROR object
while True:
try:
data = self._sock.recv(DEFAULT_BUFFER_SIZE) # type: ignore[union-attr]
data = self._sock_reader(DEFAULT_BUFFER_SIZE) # type: ignore[union-attr]
except OSError as e:
errno = e.errno
if errno == EAGAIN or errno == EWOULDBLOCK:
@ -650,7 +657,9 @@ class Unmarshaller:
self._msg_len = (
self._header_len + (-self._header_len & 7) + self._body_len
) # align 8
self._readers = self._readers_by_type[endian]
if self._endian != endian:
self._readers = self._readers_by_type[endian]
self._endian = endian
def _read_body(self) -> None:
"""Read the body of the message."""

View File

@ -435,14 +435,12 @@ class Variant:
)
@lru_cache(maxsize=None)
def get_signature_tree(signature: str) -> SignatureTree:
"""Get a signature tree for the given signature.
get_signature_tree = lru_cache(maxsize=None)(SignatureTree)
"""Get a signature tree for the given signature.
:param signature: The signature to get a tree for.
:type signature: str
:param signature: The signature to get a tree for.
:type signature: str
:returns: The signature tree for the given signature.
:rtype: :class:`SignatureTree`
"""
return SignatureTree(signature)
:returns: The signature tree for the given signature.
:rtype: :class:`SignatureTree`
"""