Skip to content

Commit e6a32f8

Browse files
committed
[perf] Use FastBuffer instead of Buffer#subarray()
`Buffer.prototype.subarray()` performance is subpar on Node.js < 16.15.0.
1 parent 9e0fd77 commit e6a32f8

File tree

3 files changed

+27
-6
lines changed

3 files changed

+27
-6
lines changed

lib/buffer-util.js

+5-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

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

5+
const FastBuffer = Buffer[Symbol.species];
6+
57
/**
68
* Merges an array of buffers into a new buffer.
79
*
@@ -23,7 +25,9 @@ function concat(list, totalLength) {
2325
offset += buf.length;
2426
}
2527

26-
if (offset < totalLength) return target.subarray(0, offset);
28+
if (offset < totalLength) {
29+
return new FastBuffer(target.buffer, target.byteOffset, offset);
30+
}
2731

2832
return target;
2933
}

lib/permessage-deflate.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const bufferUtil = require('./buffer-util');
66
const Limiter = require('./limiter');
77
const { kStatusCode } = require('./constants');
88

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

440-
if (fin) data = data.subarray(0, data.length - 4);
441+
if (fin) {
442+
data = new FastBuffer(data.buffer, data.byteOffset, data.length - 4);
443+
}
441444

442445
//
443446
// Ensure that the callback will not be called again in

lib/receiver.js

+18-4
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const {
1212
const { concat, toArrayBuffer, unmask } = require('./buffer-util');
1313
const { isValidStatusCode, isValidUTF8 } = require('./validation');
1414

15+
const FastBuffer = Buffer[Symbol.species];
1516
const GET_INFO = 0;
1617
const GET_PAYLOAD_LENGTH_16 = 1;
1718
const GET_PAYLOAD_LENGTH_64 = 2;
@@ -97,8 +98,13 @@ class Receiver extends Writable {
9798

9899
if (n < this._buffers[0].length) {
99100
const buf = this._buffers[0];
100-
this._buffers[0] = buf.subarray(n);
101-
return buf.subarray(0, n);
101+
this._buffers[0] = new FastBuffer(
102+
buf.buffer,
103+
buf.byteOffset + n,
104+
buf.length - n
105+
);
106+
107+
return new FastBuffer(buf.buffer, buf.byteOffset, n);
102108
}
103109

104110
const dst = Buffer.allocUnsafe(n);
@@ -111,7 +117,11 @@ class Receiver extends Writable {
111117
dst.set(this._buffers.shift(), offset);
112118
} else {
113119
dst.set(new Uint8Array(buf.buffer, buf.byteOffset, n), offset);
114-
this._buffers[0] = buf.subarray(n);
120+
this._buffers[0] = new FastBuffer(
121+
buf.buffer,
122+
buf.byteOffset + n,
123+
buf.length - n
124+
);
115125
}
116126

117127
n -= buf.length;
@@ -562,7 +572,11 @@ class Receiver extends Writable {
562572
);
563573
}
564574

565-
const buf = data.subarray(2);
575+
const buf = new FastBuffer(
576+
data.buffer,
577+
data.byteOffset + 2,
578+
data.length - 2
579+
);
566580

567581
if (!this._skipUTF8Validation && !isValidUTF8(buf)) {
568582
return error(

0 commit comments

Comments
 (0)