◐ Shell
clean mode source ↗

buffer: optimize buffer.concat performance · nodejs/node@940b58c

@@ -51,6 +51,7 @@ const {

5151

TypedArrayPrototypeGetLength,

5252

TypedArrayPrototypeSet,

5353

TypedArrayPrototypeSlice,

54+

TypedArrayPrototypeSubarray,

5455

Uint8Array,

5556

} = primordials;

5657

@@ -614,25 +615,55 @@ Buffer.concat = function concat(list, length) {

614615

if (length === undefined) {

615616

length = 0;

616617

for (let i = 0; i < list.length; i++) {

617-

if (list[i].length) {

618-

length += list[i].length;

618+

const buf = list[i];

619+

if (!isUint8Array(buf)) {

620+

// TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.

621+

// Instead, find the proper error code for this.

622+

throw new ERR_INVALID_ARG_TYPE(

623+

`list[${i}]`, ['Buffer', 'Uint8Array'], buf);

619624

}

625+

length += TypedArrayPrototypeGetByteLength(buf);

620626

}

621-

} else {

622-

validateOffset(length, 'length');

627+628+

const buffer = allocate(length);

629+

let pos = 0;

630+

for (let i = 0; i < list.length; i++) {

631+

const buf = list[i];

632+

const bufLength = TypedArrayPrototypeGetByteLength(buf);

633+

TypedArrayPrototypeSet(buffer, buf, pos);

634+

pos += bufLength;

635+

}

636+637+

if (pos < length) {

638+

TypedArrayPrototypeFill(buffer, 0, pos, length);

639+

}

640+

return buffer;

623641

}

624642625-

const buffer = Buffer.allocUnsafe(length);

626-

let pos = 0;

643+

validateOffset(length, 'length');

627644

for (let i = 0; i < list.length; i++) {

628-

const buf = list[i];

629-

if (!isUint8Array(buf)) {

645+

if (!isUint8Array(list[i])) {

630646

// TODO(BridgeAR): This should not be of type ERR_INVALID_ARG_TYPE.

631647

// Instead, find the proper error code for this.

632648

throw new ERR_INVALID_ARG_TYPE(

633649

`list[${i}]`, ['Buffer', 'Uint8Array'], list[i]);

634650

}

635-

pos += _copyActual(buf, buffer, pos, 0, buf.length, true);

651+

}

652+653+

const buffer = allocate(length);

654+

let pos = 0;

655+

for (let i = 0; i < list.length; i++) {

656+

const buf = list[i];

657+

const bufLength = TypedArrayPrototypeGetByteLength(buf);

658+

if (pos + bufLength > length) {

659+

TypedArrayPrototypeSet(buffer,

660+

TypedArrayPrototypeSubarray(buf, 0, length - pos),

661+

pos);

662+

pos = length;

663+

break;

664+

}

665+

TypedArrayPrototypeSet(buffer, buf, pos);

666+

pos += bufLength;

636667

}

637668638669

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