Skip to content

Commit

Permalink
buffer: improve concat() performance
Browse files Browse the repository at this point in the history
PR-URL: #31522
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rich Trott <rtrott@gmail.com>
  • Loading branch information
mscdex authored and codebytere committed Feb 17, 2020
1 parent f04576e commit 769154d
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
23 changes: 23 additions & 0 deletions benchmark/buffers/buffer-concat-fill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
'use strict';
const common = require('../common.js');

const bench = common.createBenchmark(main, {
extraSize: [1, 256, 4 * 256],
n: [8e5]
});

function main({ n, extraSize }) {
const pieces = 4;
const pieceSize = 256;

const list = Array.from({ length: pieces })
.fill(Buffer.allocUnsafe(pieceSize));

const totalLength = (pieces * pieceSize) + extraSize;

bench.start();
for (let i = 0; i < n; i++) {
Buffer.concat(list, totalLength);
}
bench.end(n);
}
9 changes: 6 additions & 3 deletions lib/buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,10 @@ function _copy(source, target, targetStart, sourceStart, sourceEnd) {
sourceStart);
}

return _copyActual(source, target, targetStart, sourceStart, sourceEnd);
}

function _copyActual(source, target, targetStart, sourceStart, sourceEnd) {
if (sourceEnd - sourceStart > target.length - targetStart)
sourceEnd = sourceStart + target.length - targetStart;

Expand Down Expand Up @@ -568,16 +572,15 @@ Buffer.concat = function concat(list, length) {
throw new ERR_INVALID_ARG_TYPE(
`list[${i}]`, ['Buffer', 'Uint8Array'], list[i]);
}
_copy(buf, buffer, pos);
pos += buf.length;
pos += _copyActual(buf, buffer, pos, 0, buf.length);
}

// Note: `length` is always equal to `buffer.length` at this point
if (pos < length) {
// Zero-fill the remaining bytes if the specified `length` was more than
// the actual total length, i.e. if we have some remaining allocated bytes
// there were not initialized.
buffer.fill(0, pos, length);
TypedArrayFill.call(buffer, 0, pos, length);
}

return buffer;
Expand Down
1 change: 1 addition & 0 deletions test/benchmark/test-benchmark-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ runBenchmark('buffers',
'difflen=false',
'encoding=utf8',
'endian=BE',
'extraSize=1',
'len=256',
'linesCount=1',
'method=',
Expand Down

0 comments on commit 769154d

Please sign in to comment.