Skip to content

Commit

Permalink
Optimize serializing TypedArrays
Browse files Browse the repository at this point in the history
  • Loading branch information
overlookmotel committed Oct 2, 2023
1 parent 82ef51c commit 5a17a5f
Showing 1 changed file with 10 additions and 25 deletions.
35 changes: 10 additions & 25 deletions lib/serialize/buffers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
* Serialize buffers
* ------------------*/

/* eslint-disable no-bitwise */

'use strict';

// Modules
Expand All @@ -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.
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit 5a17a5f

Please sign in to comment.