From 01dcf575d3daac35cf22482b0c7f299111093231 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 17 Oct 2024 14:57:16 -1000 Subject: [PATCH] Improve performance of WebSocketReader Reuses the same idea as https://github.com/aio-libs/yarl/pull/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 --- aiohttp/http_websocket.py | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/aiohttp/http_websocket.py b/aiohttp/http_websocket.py index 268f1b624d..e32ac311b3 100644 --- a/aiohttp/http_websocket.py +++ b/aiohttp/http_websocket.py @@ -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): @@ -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] @@ -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(