Skip to content

Commit 06bc2de

Browse files
mscdexcodebytere
authored andcommittedMar 30, 2020
buffer: improve from() performance
PR-URL: #31615 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
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

+38-16
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
function main({ len, n, source }) {
21-
const array = new Array(len).fill(42);
22-
const arrayBuf = new ArrayBuffer(len);
23-
const str = 'a'.repeat(len);
24-
const buffer = Buffer.allocUnsafe(len);
25-
const uint8array = new Uint8Array(len);
26-
const obj = { length: null }; // Results in a new, empty Buffer
27-
2823
let i = 0;
2924

3025
switch (source) {
31-
case 'array':
26+
case 'array': {
27+
const array = new Array(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+
const arrayBuf = new ArrayBuffer(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+
const arrayBuf = new ArrayBuffer(len);
4646
const offset = ~~(len / 4);
4747
const length = ~~(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+
const buffer = 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+
const uint8array = new Uint8Array(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+
const uint16array = new Uint16Array(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+
const str = '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+
const str = '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+
const str = '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+
const obj = { 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

+13-16
Original file line numberDiff line numberDiff line change
@@ -452,14 +452,6 @@ function fromString(string, encoding) {
452452
return fromStringFast(string, ops);
453453
}
454454

455-
function fromArrayLike(obj) {
456-
const length = obj.length;
457-
const b = allocate(length);
458-
for (let i = 0; i < length; i++)
459-
b[i] = obj[i];
460-
return b;
461-
}
462-
463455
function fromArrayBuffer(obj, byteOffset, length) {
464456
// Convert byteOffset to integer
465457
if (byteOffset === undefined) {
@@ -491,17 +483,22 @@ function fromArrayBuffer(obj, byteOffset, length) {
491483
return new FastBuffer(obj, byteOffset, length);
492484
}
493485

494-
function fromObject(obj) {
495-
if (isUint8Array(obj)) {
496-
const b = allocate(obj.length);
497-
498-
if (b.length === 0)
499-
return b;
500-
501-
_copy(obj, b, 0, 0, obj.length);
486+
function fromArrayLike(obj) {
487+
if (obj.length <= 0)
488+
return new FastBuffer();
489+
if (obj.length < (Buffer.poolSize >>> 1)) {
490+
if (obj.length > (poolSize - poolOffset))
491+
createPool();
492+
const b = new FastBuffer(allocPool, poolOffset, obj.length);
493+
b.set(obj, 0);
494+
poolOffset += obj.length;
495+
alignPool();
502496
return b;
503497
}
498+
return new FastBuffer(obj);
499+
}
504500

501+
function fromObject(obj) {
505502
if (obj.length !== undefined || isAnyArrayBuffer(obj.buffer)) {
506503
if (typeof obj.length !== 'number') {
507504
return new FastBuffer();

0 commit comments

Comments
 (0)
Please sign in to comment.