Skip to content

Commit

Permalink
buffer: improve from() performance
Browse files Browse the repository at this point in the history
PR-URL: #31615
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
  • Loading branch information
mscdex authored and codebytere committed Feb 17, 2020
1 parent 161db60 commit 519134d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 32 deletions.
54 changes: 38 additions & 16 deletions benchmark/buffers/buffer-from.js
Expand Up @@ -12,37 +12,37 @@ const bench = common.createBenchmark(main, {
'string-utf8',
'string-base64',
'object',
'uint8array',
'uint16array',
],
len: [100, 2048],
n: [8e5]
});

function main({ len, n, source }) {
const array = new Array(len).fill(42);
const arrayBuf = new ArrayBuffer(len);
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

let i = 0;

switch (source) {
case 'array':
case 'array': {
const array = new Array(len).fill(42);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(array);
}
bench.end(n);
break;
case 'arraybuffer':
}
case 'arraybuffer': {
const arrayBuf = new ArrayBuffer(len);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(arrayBuf);
}
bench.end(n);
break;
case 'arraybuffer-middle':
}
case 'arraybuffer-middle': {
const arrayBuf = new ArrayBuffer(len);
const offset = ~~(len / 4);
const length = ~~(len / 2);
bench.start();
Expand All @@ -51,48 +51,70 @@ function main({ len, n, source }) {
}
bench.end(n);
break;
case 'buffer':
}
case 'buffer': {
const buffer = Buffer.allocUnsafe(len);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(buffer);
}
bench.end(n);
break;
case 'uint8array':
}
case 'uint8array': {
const uint8array = new Uint8Array(len);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(uint8array);
}
bench.end(n);
break;
case 'string':
}
case 'uint16array': {
const uint16array = new Uint16Array(len);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(uint16array);
}
bench.end(n);
break;
}
case 'string': {
const str = 'a'.repeat(len);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(str);
}
bench.end(n);
break;
case 'string-utf8':
}
case 'string-utf8': {
const str = 'a'.repeat(len);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(str, 'utf8');
}
bench.end(n);
break;
case 'string-base64':
}
case 'string-base64': {
const str = 'a'.repeat(len);
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(str, 'base64');
}
bench.end(n);
break;
case 'object':
}
case 'object': {
const obj = { length: null }; // Results in a new, empty Buffer
bench.start();
for (i = 0; i < n; i++) {
Buffer.from(obj);
}
bench.end(n);
break;
}
default:
assert.fail('Should not get here');
}
Expand Down
29 changes: 13 additions & 16 deletions lib/buffer.js
Expand Up @@ -452,14 +452,6 @@ function fromString(string, encoding) {
return fromStringFast(string, ops);
}

function fromArrayLike(obj) {
const length = obj.length;
const b = allocate(length);
for (let i = 0; i < length; i++)
b[i] = obj[i];
return b;
}

function fromArrayBuffer(obj, byteOffset, length) {
// Convert byteOffset to integer
if (byteOffset === undefined) {
Expand Down Expand Up @@ -491,17 +483,22 @@ function fromArrayBuffer(obj, byteOffset, length) {
return new FastBuffer(obj, byteOffset, length);
}

function fromObject(obj) {
if (isUint8Array(obj)) {
const b = allocate(obj.length);

if (b.length === 0)
return b;

_copy(obj, b, 0, 0, obj.length);
function fromArrayLike(obj) {
if (obj.length <= 0)
return new FastBuffer();
if (obj.length < (Buffer.poolSize >>> 1)) {
if (obj.length > (poolSize - poolOffset))
createPool();
const b = new FastBuffer(allocPool, poolOffset, obj.length);
b.set(obj, 0);
poolOffset += obj.length;
alignPool();
return b;
}
return new FastBuffer(obj);
}

function fromObject(obj) {
if (obj.length !== undefined || isAnyArrayBuffer(obj.buffer)) {
if (typeof obj.length !== 'number') {
return new FastBuffer();
Expand Down

0 comments on commit 519134d

Please sign in to comment.