Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4810e4b

Browse filesBrowse files
gurgundayaduh95
authored andcommitted
buffer: speed up concat via TypedArray#set
PR-URL: #60399 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
1 parent a38e2f5 commit 4810e4b
Copy full SHA for 4810e4b

File tree

Expand file treeCollapse file tree

3 files changed

+32
-3
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

3 files changed

+32
-3
lines changed
Open diff view settings
Collapse file

‎lib/buffer.js‎

Copy file name to clipboardExpand all lines: lib/buffer.js
+7-3Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ function copyImpl(source, target, targetStart, sourceStart, sourceEnd) {
240240
return _copyActual(source, target, targetStart, sourceStart, sourceEnd);
241241
}
242242

243-
function _copyActual(source, target, targetStart, sourceStart, sourceEnd) {
243+
function _copyActual(source, target, targetStart, sourceStart, sourceEnd, isUint8Copy = false) {
244244
if (sourceEnd - sourceStart > target.byteLength - targetStart)
245245
sourceEnd = sourceStart + target.byteLength - targetStart;
246246

@@ -252,7 +252,11 @@ function _copyActual(source, target, targetStart, sourceStart, sourceEnd) {
252252
if (nb <= 0)
253253
return 0;
254254

255-
_copy(source, target, targetStart, sourceStart, nb);
255+
if (sourceStart === 0 && nb === sourceLen && (isUint8Copy || isUint8Array(target))) {
256+
TypedArrayPrototypeSet(target, source, targetStart);
257+
} else {
258+
_copy(source, target, targetStart, sourceStart, nb);
259+
}
256260

257261
return nb;
258262
}
@@ -600,7 +604,7 @@ Buffer.concat = function concat(list, length) {
600604
throw new ERR_INVALID_ARG_TYPE(
601605
`list[${i}]`, ['Buffer', 'Uint8Array'], list[i]);
602606
}
603-
pos += _copyActual(buf, buffer, pos, 0, buf.length);
607+
pos += _copyActual(buf, buffer, pos, 0, buf.length, true);
604608
}
605609

606610
// Note: `length` is always equal to `buffer.length` at this point
Collapse file

‎test/parallel/test-buffer-concat.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-buffer-concat.js
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ assert.throws(() => {
7676
const random10 = common.hasCrypto ?
7777
require('crypto').randomBytes(10) :
7878
Buffer.alloc(10, 1);
79+
const derived18 = Buffer.alloc(18);
80+
for (let i = 0, j = 0; i < 18; i++) {
81+
if (i < 10)
82+
derived18[i] = random10[i];
83+
else
84+
derived18[i] = random10[j++];
85+
}
7986
const empty = Buffer.alloc(0);
8087

8188
assert.notDeepStrictEqual(random10, empty);
@@ -85,6 +92,7 @@ assert.deepStrictEqual(Buffer.concat([], 100), empty);
8592
assert.deepStrictEqual(Buffer.concat([random10], 0), empty);
8693
assert.deepStrictEqual(Buffer.concat([random10], 10), random10);
8794
assert.deepStrictEqual(Buffer.concat([random10, random10], 10), random10);
95+
assert.deepStrictEqual(Buffer.concat([random10, random10], 18), derived18);
8896
assert.deepStrictEqual(Buffer.concat([empty, random10]), random10);
8997
assert.deepStrictEqual(Buffer.concat([random10, empty, empty]), random10);
9098

Collapse file

‎test/parallel/test-buffer-copy.js‎

Copy file name to clipboardExpand all lines: test/parallel/test-buffer-copy.js
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,23 @@ b.copy(c, 'not a valid offset');
226226
// Make sure this acted like a regular copy with `0` offset.
227227
assert.deepStrictEqual(c, b.slice(0, c.length));
228228

229+
// Copy into a Uint16Array target; bytes are packed into 16-bit elements.
230+
{
231+
const x = new Uint16Array(4);
232+
const buf = Buffer.of(1, 2, 3, 4);
233+
const copied = buf.copy(x);
234+
assert.strictEqual(copied, 4);
235+
assert.ok(x instanceof Uint16Array);
236+
const bytes = new Uint8Array(x.buffer, x.byteOffset, 4);
237+
assert.deepStrictEqual(Array.from(bytes), [1, 2, 3, 4]);
238+
const remaining = new Uint8Array(
239+
x.buffer,
240+
x.byteOffset + 4,
241+
x.byteLength - 4
242+
);
243+
assert.ok(remaining.every((b) => b === 0));
244+
}
245+
229246
{
230247
c.fill('C');
231248
assert.throws(() => {

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.