Skip to content

Commit 06bc2de

Browse files
mscdexcodebytere
authored andcommitted
buffer: improve from() performance
PR-URL: #31615 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Anna Henningsen <[email protected]>
1 parent 041408d commit 06bc2de

File tree

2 files changed

+51
-32
lines changed

2 files changed

+51
-32
lines changed

‎benchmark/buffers/buffer-from.js‎

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,37 +12,37 @@ const bench = common.createBenchmark(main,{
1212
'string-utf8',
1313
'string-base64',
1414
'object',
15+
'uint8array',
16+
'uint16array',
1517
],
1618
len: [100,2048],
1719
n: [8e5]
1820
});
1921

2022
functionmain({ len, n, source }){
21-
constarray=newArray(len).fill(42);
22-
constarrayBuf=newArrayBuffer(len);
23-
conststr='a'.repeat(len);
24-
constbuffer=Buffer.allocUnsafe(len);
25-
constuint8array=newUint8Array(len);
26-
constobj={length: null};// Results in a new, empty Buffer
27-
2823
leti=0;
2924

3025
switch(source){
31-
case'array':
26+
case'array': {
27+
constarray=newArray(len).fill(42);
3228
bench.start();
3329
for(i=0;i<n;i++){
3430
Buffer.from(array);
3531
}
3632
bench.end(n);
3733
break;
38-
case'arraybuffer':
34+
}
35+
case'arraybuffer': {
36+
constarrayBuf=newArrayBuffer(len);
3937
bench.start();
4038
for(i=0;i<n;i++){
4139
Buffer.from(arrayBuf);
4240
}
4341
bench.end(n);
4442
break;
45-
case'arraybuffer-middle':
43+
}
44+
case'arraybuffer-middle': {
45+
constarrayBuf=newArrayBuffer(len);
4646
constoffset=~~(len/4);
4747
constlength=~~(len/2);
4848
bench.start();
@@ -51,48 +51,70 @@ function main({len, n, source }){
5151
}
5252
bench.end(n);
5353
break;
54-
case'buffer':
54+
}
55+
case'buffer': {
56+
constbuffer=Buffer.allocUnsafe(len);
5557
bench.start();
5658
for(i=0;i<n;i++){
5759
Buffer.from(buffer);
5860
}
5961
bench.end(n);
6062
break;
61-
case'uint8array':
63+
}
64+
case'uint8array': {
65+
constuint8array=newUint8Array(len);
6266
bench.start();
6367
for(i=0;i<n;i++){
6468
Buffer.from(uint8array);
6569
}
6670
bench.end(n);
6771
break;
68-
case'string':
72+
}
73+
case'uint16array': {
74+
constuint16array=newUint16Array(len);
75+
bench.start();
76+
for(i=0;i<n;i++){
77+
Buffer.from(uint16array);
78+
}
79+
bench.end(n);
80+
break;
81+
}
82+
case'string': {
83+
conststr='a'.repeat(len);
6984
bench.start();
7085
for(i=0;i<n;i++){
7186
Buffer.from(str);
7287
}
7388
bench.end(n);
7489
break;
75-
case'string-utf8':
90+
}
91+
case'string-utf8': {
92+
conststr='a'.repeat(len);
7693
bench.start();
7794
for(i=0;i<n;i++){
7895
Buffer.from(str,'utf8');
7996
}
8097
bench.end(n);
8198
break;
82-
case'string-base64':
99+
}
100+
case'string-base64': {
101+
conststr='a'.repeat(len);
83102
bench.start();
84103
for(i=0;i<n;i++){
85104
Buffer.from(str,'base64');
86105
}
87106
bench.end(n);
88107
break;
89-
case'object':
108+
}
109+
case'object': {
110+
constobj={length: null};// Results in a new, empty Buffer
90111
bench.start();
91112
for(i=0;i<n;i++){
92113
Buffer.from(obj);
93114
}
94115
bench.end(n);
95116
break;
117+
}
96118
default:
97119
assert.fail('Should not get here');
98120
}

‎lib/buffer.js‎

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -452,14 +452,6 @@ function fromString(string, encoding){
452452
returnfromStringFast(string,ops);
453453
}
454454

455-
functionfromArrayLike(obj){
456-
constlength=obj.length;
457-
constb=allocate(length);
458-
for(leti=0;i<length;i++)
459-
b[i]=obj[i];
460-
returnb;
461-
}
462-
463455
functionfromArrayBuffer(obj,byteOffset,length){
464456
// Convert byteOffset to integer
465457
if(byteOffset===undefined){
@@ -491,17 +483,22 @@ function fromArrayBuffer(obj, byteOffset, length){
491483
returnnewFastBuffer(obj,byteOffset,length);
492484
}
493485

494-
functionfromObject(obj){
495-
if(isUint8Array(obj)){
496-
constb=allocate(obj.length);
497-
498-
if(b.length===0)
499-
returnb;
500-
501-
_copy(obj,b,0,0,obj.length);
486+
functionfromArrayLike(obj){
487+
if(obj.length<=0)
488+
returnnewFastBuffer();
489+
if(obj.length<(Buffer.poolSize>>>1)){
490+
if(obj.length>(poolSize-poolOffset))
491+
createPool();
492+
constb=newFastBuffer(allocPool,poolOffset,obj.length);
493+
b.set(obj,0);
494+
poolOffset+=obj.length;
495+
alignPool();
502496
returnb;
503497
}
498+
returnnewFastBuffer(obj);
499+
}
504500

501+
functionfromObject(obj){
505502
if(obj.length!==undefined||isAnyArrayBuffer(obj.buffer)){
506503
if(typeofobj.length!=='number'){
507504
returnnewFastBuffer();

0 commit comments

Comments
(0)