From d043a6d72cbf683c70f7eb4b9b3c09003afd2683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 27 Apr 2023 12:47:52 +0200 Subject: [PATCH] perf(ext/websocket): various performance improvements (#18862) - No need to wrap buffer in a `new DataView()` - Deferred ops are still eagerly polled, but resolved on the next tick of the event loop, we don't want them to be eagerly polled - Using "core.opAsync"/"core.opAsync2" incurs additional cost of looking up these functions on each call. Similarly with "ops.*" --------- Co-authored-by: Divy Srivastava --- ext/websocket/01_websocket.js | 30 +++++++++++++++--------------- ext/websocket/lib.rs | 2 +- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js index cb9f756d21..7b23df80f0 100644 --- a/ext/websocket/01_websocket.js +++ b/ext/websocket/01_websocket.js @@ -3,7 +3,10 @@ /// const core = globalThis.Deno.core; -const ops = core.ops; +const { opAsync, opAsync2 } = core; +// deno-lint-ignore camelcase +const op_ws_check_permission_and_cancel_handle = + core.ops.op_ws_check_permission_and_cancel_handle; import { URL } from "ext:deno_url/00_url.js"; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { HTTP_TOKEN_CODE_POINT_RE } from "ext:deno_web/00_infra.js"; @@ -210,7 +213,7 @@ class WebSocket extends EventTarget { this[_url] = wsURL.href; this[_role] = CLIENT; - ops.op_ws_check_permission_and_cancel_handle( + op_ws_check_permission_and_cancel_handle( "WebSocket.abort()", this[_url], false, @@ -247,7 +250,7 @@ class WebSocket extends EventTarget { } PromisePrototypeThen( - core.opAsync( + opAsync( "op_ws_create", "new WebSocket()", wsURL.href, @@ -260,7 +263,7 @@ class WebSocket extends EventTarget { if (this[_readyState] === CLOSING) { PromisePrototypeThen( - core.opAsync("op_ws_close", this[_rid]), + opAsync("op_ws_close", this[_rid]), () => { this[_readyState] = CLOSED; @@ -316,7 +319,7 @@ class WebSocket extends EventTarget { const sendTypedArray = (view, byteLength) => { this[_bufferedAmount] += byteLength; PromisePrototypeThen( - core.opAsync2( + opAsync2( "op_ws_send_binary", this[_rid], view, @@ -345,16 +348,13 @@ class WebSocket extends EventTarget { sendTypedArray(data, TypedArrayPrototypeGetByteLength(data)); } } else if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, data)) { - sendTypedArray( - new DataView(data), - ArrayBufferPrototypeGetByteLength(data), - ); + sendTypedArray(data, ArrayBufferPrototypeGetByteLength(data)); } else { const string = String(data); const d = core.encode(string); this[_bufferedAmount] += TypedArrayPrototypeGetByteLength(d); PromisePrototypeThen( - core.opAsync2( + opAsync2( "op_ws_send_text", this[_rid], string, @@ -413,7 +413,7 @@ class WebSocket extends EventTarget { this[_readyState] = CLOSING; PromisePrototypeCatch( - core.opAsync( + opAsync( "op_ws_close", this[_rid], code, @@ -438,7 +438,7 @@ class WebSocket extends EventTarget { async [_eventLoop]() { while (this[_readyState] !== CLOSED) { - const { 0: kind, 1: value } = await core.opAsync2( + const { 0: kind, 1: value } = await opAsync2( "op_ws_next_event", this[_rid], ); @@ -501,7 +501,7 @@ class WebSocket extends EventTarget { if (prevState === OPEN) { try { - await core.opAsync( + await opAsync( "op_ws_close", this[_rid], code, @@ -530,12 +530,12 @@ class WebSocket extends EventTarget { clearTimeout(this[_idleTimeoutTimeout]); this[_idleTimeoutTimeout] = setTimeout(async () => { if (this[_readyState] === OPEN) { - await core.opAsync("op_ws_send_ping", this[_rid]); + await opAsync("op_ws_send_ping", this[_rid]); this[_idleTimeoutTimeout] = setTimeout(async () => { if (this[_readyState] === OPEN) { this[_readyState] = CLOSING; const reason = "No response from ping frame."; - await core.opAsync( + await opAsync( "op_ws_close", this[_rid], 1001, diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index df4127d273..9ea341fbb6 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -427,7 +427,7 @@ pub async fn op_ws_close( Ok(()) } -#[op(deferred)] +#[op(fast)] pub async fn op_ws_next_event( state: Rc>, rid: ResourceId,