Skip to content

Commit

Permalink
Improve performance of WebSocketReader
Browse files Browse the repository at this point in the history
Reuses the same idea as aio-libs/yarl#1316

Calling tuple.__new__ is much faster because it avoids
the extra runtime lambda
https://github.com/python/cpython/blob/d83fcf8371f2f33c7797bc8f5423a8bca8c46e5c/Lib/collections/__init__.py#L441
  • Loading branch information
bdraco committed Oct 18, 2024
1 parent da0099d commit 01dcf57
Showing 1 changed file with 14 additions and 8 deletions.
22 changes: 14 additions & 8 deletions aiohttp/http_websocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,8 @@ def json(self, *, loads: Callable[[Any], Any] = json.loads) -> Any:
return loads(self.data)


WS_CLOSED_MESSAGE = WSMessage(WSMsgType.CLOSED, None, None)
WS_CLOSING_MESSAGE = WSMessage(WSMsgType.CLOSING, None, None)
WS_CLOSED_MESSAGE = tuple.__new__(WSMessage, (WSMsgType.CLOSED, None, None))
WS_CLOSING_MESSAGE = tuple.__new__(WSMessage, (WSMsgType.CLOSING, None, None))


class WebSocketError(Exception):
Expand Down Expand Up @@ -402,10 +402,12 @@ def _feed_data(self, data: bytes) -> None:
WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message"
) from exc

self.queue.feed_data(WSMessage(WSMsgType.TEXT, text, ""))
msg = tuple.__new__(WSMessage, (WSMsgType.TEXT, text, ""))
self.queue.feed_data(msg)
continue

self.queue.feed_data(WSMessage(WSMsgType.BINARY, payload_merged, ""))
msg = tuple.__new__(WSMessage, (WSMsgType.BINARY, payload_merged, ""))
self.queue.feed_data(msg)
elif opcode == WSMsgType.CLOSE:
if len(payload) >= 2:
close_code = UNPACK_CLOSE_CODE(payload[:2])[0]
Expand All @@ -420,22 +422,26 @@ def _feed_data(self, data: bytes) -> None:
raise WebSocketError(
WSCloseCode.INVALID_TEXT, "Invalid UTF-8 text message"
) from exc
msg = WSMessage(WSMsgType.CLOSE, close_code, close_message)
msg = tuple.__new__(
WSMessage, (WSMsgType.CLOSE, close_code, close_message)
)
elif payload:
raise WebSocketError(
WSCloseCode.PROTOCOL_ERROR,
f"Invalid close frame: {fin} {opcode} {payload!r}",
)
else:
msg = WSMessage(WSMsgType.CLOSE, 0, "")
msg = tuple.__new__(WSMessage, (WSMsgType.CLOSE, 0, ""))

self.queue.feed_data(msg)

elif opcode == WSMsgType.PING:
self.queue.feed_data(WSMessage(WSMsgType.PING, payload, ""))
msg = tuple.__new__(WSMessage, (WSMsgType.PING, payload, ""))
self.queue.feed_data(msg)

elif opcode == WSMsgType.PONG:
self.queue.feed_data(WSMessage(WSMsgType.PONG, payload, ""))
msg = tuple.__new__(WSMessage, (WSMsgType.PONG, payload, ""))
self.queue.feed_data(msg)

else:
raise WebSocketError(
Expand Down

0 comments on commit 01dcf57

Please sign in to comment.