From d5a1a46c67e5b789a8e27087175a79a49b1dfd82 Mon Sep 17 00:00:00 2001 From: tsctx <91457664+tsctx@users.noreply.github.com> Date: Sun, 5 May 2024 20:03:14 +0900 Subject: [PATCH] websocket: improve performance of generate mask --- benchmarks/websocket/generate-mask.mjs | 22 ++++++++++++++++++++++ lib/web/websocket/websocket.js | 21 ++++++++++++--------- 2 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 benchmarks/websocket/generate-mask.mjs diff --git a/benchmarks/websocket/generate-mask.mjs b/benchmarks/websocket/generate-mask.mjs new file mode 100644 index 00000000000..bf145ee366d --- /dev/null +++ b/benchmarks/websocket/generate-mask.mjs @@ -0,0 +1,22 @@ +import { randomFillSync, randomBytes } from 'node:crypto' +import { bench, group, run } from 'mitata' + +const BUFFER_SIZE = 16384 + +const buf = randomFillSync(Buffer.allocUnsafe(BUFFER_SIZE), 0, BUFFER_SIZE) +let bufIdx = 0 + +function generateMask () { + if (bufIdx + 4 > BUFFER_SIZE) { + bufIdx = 0 + randomFillSync(buf, 0, BUFFER_SIZE) + } + return [buf[bufIdx++], buf[bufIdx++], buf[bufIdx++], buf[bufIdx++]] +} + +group('generate', () => { + bench('generateMask', () => generateMask()) + bench('crypto.randomBytes(4)', () => randomBytes(4)) +}) + +await run() diff --git a/lib/web/websocket/websocket.js b/lib/web/websocket/websocket.js index 00e81cbafca..8dd447204d9 100644 --- a/lib/web/websocket/websocket.js +++ b/lib/web/websocket/websocket.js @@ -2,7 +2,7 @@ const { webidl } = require('../fetch/webidl') const { URLSerializer } = require('../fetch/data-url') -const { getGlobalOrigin } = require('../fetch/global') +const { environmentSettingsObject } = require('../fetch/util') const { staticPropertyDescriptors, states, sentCloseFrameState, opcodes, emptyBuffer } = require('./constants') const { kWebSocketURL, @@ -29,6 +29,8 @@ const { kEnumerableProperty, isBlobLike } = require('../../core/util') const { getGlobalDispatcher } = require('../../global') const { types } = require('node:util') +const FastBuffer = Buffer[Symbol.species] + let experimentalWarned = false // https://websockets.spec.whatwg.org/#interface-definition @@ -67,7 +69,7 @@ class WebSocket extends EventTarget { protocols = options.protocols // 1. Let baseURL be this's relevant settings object's API base URL. - const baseURL = getGlobalOrigin() + const baseURL = environmentSettingsObject.settingsObject.baseUrl // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. let urlRecord @@ -323,7 +325,7 @@ class WebSocket extends EventTarget { // increase the bufferedAmount attribute by the length of the // ArrayBuffer in bytes. - const value = Buffer.from(data) + const value = new FastBuffer(data) const frame = new WebsocketFrameSend(value) const buffer = frame.createFrame(opcodes.BINARY) @@ -344,7 +346,7 @@ class WebSocket extends EventTarget { // not throw an exception must increase the bufferedAmount attribute // by the length of data’s buffer in bytes. - const ab = Buffer.from(data, data.byteOffset, data.byteLength) + const ab = new FastBuffer(data, data.byteOffset, data.byteLength) const frame = new WebsocketFrameSend(ab) const buffer = frame.createFrame(opcodes.BINARY) @@ -368,7 +370,7 @@ class WebSocket extends EventTarget { const frame = new WebsocketFrameSend() data.arrayBuffer().then((ab) => { - const value = Buffer.from(ab) + const value = new FastBuffer(ab) frame.frameData = value const buffer = frame.createFrame(opcodes.BINARY) @@ -505,9 +507,7 @@ class WebSocket extends EventTarget { set binaryType (type) { webidl.brandCheck(this, WebSocket) - if (type !== 'blob' && type !== 'arraybuffer') { - this[kBinaryType] = 'blob' - } else { + if (type === 'blob' || type === 'arraybuffer') { this[kBinaryType] = type } } @@ -644,7 +644,10 @@ webidl.converters.WebSocketSendData = function (V) { } } - return webidl.converters.USVString(V) + // This is done with `Buffer.from`. + // "To convert a string into a scalar value string, replace any surrogates + // with U+FFFD." + return webidl.converters.DOMString(V) } module.exports = {