Skip to content

Commit

Permalink
[perf] Use FastBuffer instead of Buffer#subarray()
Browse files Browse the repository at this point in the history
`Buffer.prototype.subarray()` performance is subpar on
Node.js < 16.15.0.
  • Loading branch information
lpinca committed Dec 13, 2022
1 parent 9e0fd77 commit e6a32f8
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 6 deletions.
6 changes: 5 additions & 1 deletion lib/buffer-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

const { EMPTY_BUFFER } = require('./constants');

const FastBuffer = Buffer[Symbol.species];

/**
* Merges an array of buffers into a new buffer.
*
Expand All @@ -23,7 +25,9 @@ function concat(list, totalLength) {
offset += buf.length;
}

if (offset < totalLength) return target.subarray(0, offset);
if (offset < totalLength) {
return new FastBuffer(target.buffer, target.byteOffset, offset);
}

return target;
}
Expand Down
5 changes: 4 additions & 1 deletion lib/permessage-deflate.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const bufferUtil = require('./buffer-util');
const Limiter = require('./limiter');
const { kStatusCode } = require('./constants');

const FastBuffer = Buffer[Symbol.species];
const TRAILER = Buffer.from([0x00, 0x00, 0xff, 0xff]);
const kPerMessageDeflate = Symbol('permessage-deflate');
const kTotalLength = Symbol('total-length');
Expand Down Expand Up @@ -437,7 +438,9 @@ class PerMessageDeflate {
this._deflate[kTotalLength]
);

if (fin) data = data.subarray(0, data.length - 4);
if (fin) {
data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);
}

//
// Ensure that the callback will not be called again in
Expand Down
22 changes: 18 additions & 4 deletions lib/receiver.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const {
const { concat, toArrayBuffer, unmask } = require('./buffer-util');
const { isValidStatusCode, isValidUTF8 } = require('./validation');

const FastBuffer = Buffer[Symbol.species];
const GET_INFO = 0;
const GET_PAYLOAD_LENGTH_16 = 1;
const GET_PAYLOAD_LENGTH_64 = 2;
Expand Down Expand Up @@ -97,8 +98,13 @@ class Receiver extends Writable {

if (n < this._buffers[0].length) {
const buf = this._buffers[0];
this._buffers[0] = buf.subarray(n);
return buf.subarray(0, n);
this._buffers[0] = new FastBuffer(
buf.buffer,
buf.byteOffset + n,
buf.length - n
);

return new FastBuffer(buf.buffer, buf.byteOffset, n);
}

const dst = Buffer.allocUnsafe(n);
Expand All @@ -111,7 +117,11 @@ class Receiver extends Writable {
dst.set(this._buffers.shift(), offset);
} else {
dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
this._buffers[0] = buf.subarray(n);
this._buffers[0] = new FastBuffer(
buf.buffer,
buf.byteOffset + n,
buf.length - n
);
}

n -= buf.length;
Expand Down Expand Up @@ -562,7 +572,11 @@ class Receiver extends Writable {
);
}

const buf = data.subarray(2);
const buf = new FastBuffer(
data.buffer,
data.byteOffset + 2,
data.length - 2
);

if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
return error(
Expand Down

0 comments on commit e6a32f8

Please sign in to comment.