From 6ff3aa6a4a40f33fcb00926dc8f3a25b870aca84 Mon Sep 17 00:00:00 2001 From: Brian White Date: Sun, 26 Jan 2020 10:01:21 -0500 Subject: [PATCH] buffer: improve concat() performance --- benchmark/buffers/buffer-concat-fill.js | 23 +++++++++++++++++++++++ lib/buffer.js | 9 ++++++--- test/benchmark/test-benchmark-buffer.js | 1 + 3 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 benchmark/buffers/buffer-concat-fill.js diff --git a/benchmark/buffers/buffer-concat-fill.js b/benchmark/buffers/buffer-concat-fill.js new file mode 100644 index 00000000000000..8fb389fe6c8639 --- /dev/null +++ b/benchmark/buffers/buffer-concat-fill.js @@ -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); +} diff --git a/lib/buffer.js b/lib/buffer.js index 5a6b75c33e5be6..bf7ae972eff6e5 100644 --- a/lib/buffer.js +++ b/lib/buffer.js @@ -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; @@ -568,8 +572,7 @@ 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 @@ -577,7 +580,7 @@ Buffer.concat = function concat(list, 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; diff --git a/test/benchmark/test-benchmark-buffer.js b/test/benchmark/test-benchmark-buffer.js index 6ce0e542a93474..57130ffb08ba3d 100644 --- a/test/benchmark/test-benchmark-buffer.js +++ b/test/benchmark/test-benchmark-buffer.js @@ -15,6 +15,7 @@ runBenchmark('buffers', 'difflen=false', 'encoding=utf8', 'endian=BE', + 'extraSize=1', 'len=256', 'linesCount=1', 'method=',