Skip to content

Commit

Permalink
buffer: improve allocation performance
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
mscdex authored and evanlucas committed Jan 4, 2017
1 parent 495213e commit 797495a
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 5 deletions.
11 changes: 10 additions & 1 deletion benchmark/buffers/buffer-from.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ const bench = common.createBenchmark(main, {
'buffer',
'uint8array',
'string',
'string-base64'
'string-base64',
'object'
],
len: [10, 2048],
n: [1024]
Expand All @@ -25,6 +26,7 @@ function main(conf) {
const str = 'a'.repeat(len);
const buffer = Buffer.allocUnsafe(len);
const uint8array = new Uint8Array(len);
const obj = { length: null }; // Results in a new, empty Buffer

var i;

Expand Down Expand Up @@ -80,6 +82,13 @@ function main(conf) {
}
bench.end(n);
break;
case 'object':
bench.start();
for (i = 0; i < n * 1024; i++) {
Buffer.from(obj);
}
bench.end(n);
break;
default:
assert.fail(null, null, 'Should not get here');
}
Expand Down
8 changes: 4 additions & 4 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ Buffer.from = function(value, encodingOrOffset, length) {

Object.setPrototypeOf(Buffer, Uint8Array);

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

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

if (err) {
// The following hides the 'assertSize' method from the
// callstack. This is done simply to hide the internal
// details of the implementation from bleeding out to users.
Error.captureStackTrace(err, assertSize);
throw err;
}
Expand Down Expand Up @@ -258,7 +258,7 @@ function fromObject(obj) {
}

if (obj) {
if ('length' in obj || isArrayBuffer(obj.buffer) ||
if (obj.length !== undefined || isArrayBuffer(obj.buffer) ||
isSharedArrayBuffer(obj.buffer)) {
if (typeof obj.length !== 'number' || obj.length !== obj.length) {
return new FastBuffer();
Expand Down

0 comments on commit 797495a

Please sign in to comment.