1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 16:19:12 -05:00

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 <dj.srivastava23@gmail.com>
This commit is contained in:
Bartek Iwańczuk 2023-04-27 12:47:52 +02:00 committed by GitHub
parent 1e331a4873
commit d043a6d72c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 16 deletions

View file

@ -3,7 +3,10 @@
/// <reference path="../../core/internal.d.ts" />
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,

View file

@ -427,7 +427,7 @@ pub async fn op_ws_close(
Ok(())
}
#[op(deferred)]
#[op(fast)]
pub async fn op_ws_next_event(
state: Rc<RefCell<OpState>>,
rid: ResourceId,