From 5a17a5f585ada9ad7a56cae6a2dbd1886476d253 Mon Sep 17 00:00:00 2001 From: overlookmotel Date: Mon, 2 Oct 2023 23:18:10 +0100 Subject: [PATCH] Optimize serializing TypedArrays --- lib/serialize/buffers.js | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/lib/serialize/buffers.js b/lib/serialize/buffers.js index 1e70bfa4..6e2d7dcb 100644 --- a/lib/serialize/buffers.js +++ b/lib/serialize/buffers.js @@ -3,8 +3,6 @@ * Serialize buffers * ------------------*/ -/* eslint-disable no-bitwise */ - 'use strict'; // Modules @@ -24,8 +22,6 @@ const bufferToString = Buffer.prototype.toString, typedArrayLengthGetter = Object.getOwnPropertyDescriptor(TypedArrayPrototype, 'byteLength').get, typedArrayOffsetGetter = Object.getOwnPropertyDescriptor(TypedArrayPrototype, 'byteOffset').get; -const bitsRegex = /^(Ui|I)nt(\d+)Array$/; - module.exports = { /** * Trace Buffer or TypedArray. @@ -112,32 +108,21 @@ registerSerializer(BUFFER_TYPE, serializeBuffer); * @returns {Object} - AST node */ function serializeTypedArray(record) { - const {type, bytes, offset, len} = record.extra, - match = type.match(bitsRegex), - isSigned = match[1] === 'I', - bytesPerChar = match[2] / 8, - maxByteValue = 256 ** bytesPerChar, - signedMaxByteValue = maxByteValue / 2; - - const buf = Buffer.from(bytes).subarray(offset, offset + len); - - const byteNodes = []; - for (let pos = 0; pos < buf.length; pos += bytesPerChar) { - let byte = 0, - byteMultiplier = 1; - for (let byteNum = 0; byteNum < bytesPerChar; byteNum++) { - byte += buf[pos + byteNum] * byteMultiplier; - byteMultiplier <<= 8; - } + const {extra} = record, + ctor = global[extra.type]; - if (isSigned && byte >= signedMaxByteValue) byte -= maxByteValue; + // eslint-disable-next-line new-cap + const buf = new ctor(extra.bytes, extra.offset, extra.len / ctor.BYTES_PER_ELEMENT); - byteNodes.push(t.numericLiteral(byte)); + const byteNodes = [], + len = buf.length; + for (let index = 0; index < len; index++) { + const val = buf[index]; + byteNodes.push(val === 0 ? null : t.numericLiteral(val)); } // `new Uint16Array([...])` - const ctor = global[type], - node = t.newExpression(this.traceAndSerializeGlobal(ctor), [t.arrayExpression(byteNodes)]); + const node = t.newExpression(this.traceAndSerializeGlobal(ctor), [t.arrayExpression(byteNodes)]); const ctorPrototypeRecord = this.traceValue(ctor.prototype, null, null); return this.wrapWithProperties(node, record, ctorPrototypeRecord, null);