Skip to content

Commit 797495a

Browse files
mscdexevanlucas
authored andcommitted
buffer: improve allocation performance
assertSize() is adjusted to be inlineable according to V8's default function size limits when determining inlineability. This results in up to 11% performance gains when allocating any kind of Buffer. Avoid avoids use of in, resulting in ~50% improvement when creating a Buffer from an array-like object. PR-URL: #10443 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Сковорода Никита Андреевич <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 495213e commit 797495a

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

benchmark/buffers/buffer-from.js

+10-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ const bench = common.createBenchmark(main, {
1010
'buffer',
1111
'uint8array',
1212
'string',
13-
'string-base64'
13+
'string-base64',
14+
'object'
1415
],
1516
len: [10, 2048],
1617
n: [1024]
@@ -25,6 +26,7 @@ function main(conf) {
2526
const str = 'a'.repeat(len);
2627
const buffer = Buffer.allocUnsafe(len);
2728
const uint8array = new Uint8Array(len);
29+
const obj = { length: null }; // Results in a new, empty Buffer
2830

2931
var i;
3032

@@ -80,6 +82,13 @@ function main(conf) {
8082
}
8183
bench.end(n);
8284
break;
85+
case 'object':
86+
bench.start();
87+
for (i = 0; i < n * 1024; i++) {
88+
Buffer.from(obj);
89+
}
90+
bench.end(n);
91+
break;
8392
default:
8493
assert.fail(null, null, 'Should not get here');
8594
}

lib/buffer.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ Buffer.from = function(value, encodingOrOffset, length) {
108108

109109
Object.setPrototypeOf(Buffer, Uint8Array);
110110

111+
// The 'assertSize' method will remove itself from the callstack when an error
112+
// occurs. This is done simply to keep the internal details of the
113+
// implementation from bleeding out to users.
111114
function assertSize(size) {
112115
let err = null;
113116

@@ -117,9 +120,6 @@ function assertSize(size) {
117120
err = new RangeError('"size" argument must not be negative');
118121

119122
if (err) {
120-
// The following hides the 'assertSize' method from the
121-
// callstack. This is done simply to hide the internal
122-
// details of the implementation from bleeding out to users.
123123
Error.captureStackTrace(err, assertSize);
124124
throw err;
125125
}
@@ -258,7 +258,7 @@ function fromObject(obj) {
258258
}
259259

260260
if (obj) {
261-
if ('length' in obj || isArrayBuffer(obj.buffer) ||
261+
if (obj.length !== undefined || isArrayBuffer(obj.buffer) ||
262262
isSharedArrayBuffer(obj.buffer)) {
263263
if (typeof obj.length !== 'number' || obj.length !== obj.length) {
264264
return new FastBuffer();

0 commit comments

Comments
 (0)