Skip to content

Commit 4a86803

Browse files
mscdexaddaleax
authored andcommitted
buffer: optimize from() and byteLength()
PR-URL: #12361 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net>
1 parent 46f2026 commit 4a86803

5 files changed

Lines changed: 129 additions & 86 deletions

File tree

benchmark/buffers/buffer-bytelength.js

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
var common = require('../common');
33

44
var bench = common.createBenchmark(main, {
5-
encoding: ['utf8', 'base64'],
5+
encoding: ['utf8', 'base64', 'buffer'],
66
len: [1, 2, 4, 16, 64, 256], // x16
77
n: [5e6]
88
});
@@ -21,21 +21,27 @@ function main(conf) {
2121
var encoding = conf.encoding;
2222

2323
var strings = [];
24-
for (var string of chars) {
25-
// Strings must be built differently, depending on encoding
26-
var data = buildString(string, len);
27-
if (encoding === 'utf8') {
28-
strings.push(data);
29-
} else if (encoding === 'base64') {
30-
// Base64 strings will be much longer than their UTF8 counterparts
31-
strings.push(Buffer.from(data, 'utf8').toString('base64'));
24+
var results;
25+
if (encoding === 'buffer') {
26+
strings = [ Buffer.alloc(len * 16, 'a') ];
27+
results = [ len * 16 ];
28+
} else {
29+
for (var string of chars) {
30+
// Strings must be built differently, depending on encoding
31+
var data = buildString(string, len);
32+
if (encoding === 'utf8') {
33+
strings.push(data);
34+
} else if (encoding === 'base64') {
35+
// Base64 strings will be much longer than their UTF8 counterparts
36+
strings.push(Buffer.from(data, 'utf8').toString('base64'));
37+
}
3238
}
33-
}
3439

35-
// Check the result to ensure it is *properly* optimized
36-
var results = strings.map(function(val) {
37-
return Buffer.byteLength(val, encoding);
38-
});
40+
// Check the result to ensure it is *properly* optimized
41+
results = strings.map(function(val) {
42+
return Buffer.byteLength(val, encoding);
43+
});
44+
}
3945

4046
bench.start();
4147
for (var i = 0; i < n; i++) {

benchmark/buffers/buffer-from.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,12 @@ const bench = common.createBenchmark(main, {
1010
'buffer',
1111
'uint8array',
1212
'string',
13+
'string-utf8',
1314
'string-base64',
1415
'object'
1516
],
1617
len: [10, 2048],
17-
n: [1024]
18+
n: [2048]
1819
});
1920

2021
function main(conf) {
@@ -75,6 +76,13 @@ function main(conf) {
7576
}
7677
bench.end(n);
7778
break;
79+
case 'string-utf8':
80+
bench.start();
81+
for (i = 0; i < n * 1024; i++) {
82+
Buffer.from(str, 'utf8');
83+
}
84+
bench.end(n);
85+
break;
7886
case 'string-base64':
7987
bench.start();
8088
for (i = 0; i < n * 1024; i++) {

lib/buffer.js

Lines changed: 90 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@
2323

2424
const binding = process.binding('buffer');
2525
const { compare: compare_, compareOffset } = binding;
26-
const { isArrayBuffer, isSharedArrayBuffer, isUint8Array } =
27-
process.binding('util');
26+
const { isAnyArrayBuffer, isUint8Array } = process.binding('util');
2827
const bindingObj = {};
2928
const internalUtil = require('internal/util');
3029

@@ -116,16 +115,19 @@ function Buffer(arg, encodingOrOffset, length) {
116115
* Buffer.from(arrayBuffer[, byteOffset[, length]])
117116
**/
118117
Buffer.from = function(value, encodingOrOffset, length) {
119-
if (typeof value === 'number')
120-
throw new TypeError('"value" argument must not be a number');
118+
if (typeof value === 'string')
119+
return fromString(value, encodingOrOffset);
121120

122-
if (isArrayBuffer(value) || isSharedArrayBuffer(value))
121+
if (isAnyArrayBuffer(value))
123122
return fromArrayBuffer(value, encodingOrOffset, length);
124123

125-
if (typeof value === 'string')
126-
return fromString(value, encodingOrOffset);