Skip to content

Commit 13a4887

Browse files
mscdexjasnell
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: nodejs#10443 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Сковорода Никита Андреевич <chalkerx@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 595b22a commit 13a4887

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

benchmark/buffers/buffer-from.js

Lines changed: 10 additions & 1 deletion
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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ Buffer.from = function(value, encodingOrOffset, length) {
109109

110110
Object.setPrototypeOf(Buffer, Uint8Array);
111111

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

@@ -121,9 +124,6 @@ function assertSize(size) {
121124
'than ' + binding.kMaxLength);
122125

123126
if (err) {
124-
// The following hides the 'assertSize' method from the
125-
// callstack. This is done simply to hide the internal
126-
// details of the implementation from bleeding out to users.
127127
Error.captureStackTrace(err, assertSize);
128128
throw err;
129129
}
@@ -263,7 +263,7 @@ function fromObject(obj) {
263263
}
264264

265265
if (obj) {
266-
if ('length' in obj || isArrayBuffer(obj.buffer) ||
266+
if (obj.length !== undefined || isArrayBuffer(obj.buffer) ||
267267
isSharedArrayBuffer(obj.buffer)) {
268268
if (typeof obj.length !== 'number' || obj.length !== obj.length) {
269269
return new FastBuffer();

0 commit comments

Comments
 (0)