util: improve format performance
This simplifies the `format()` code and significantly improves the performance. PR-URL: https://github.com/nodejs/node/pull/24981 Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com> Reviewed-By: Roman Reiss <me@silverwind.io>
This commit is contained in:
parent
d0c240f1be
commit
9752fce34d
85
lib/util.js
85
lib/util.js
@ -78,45 +78,32 @@ function format(...args) {
|
||||
return formatWithOptions(emptyOptions, ...args);
|
||||
}
|
||||
|
||||
function formatValue(val, inspectOptions) {
|
||||
const inspectTypes = ['object', 'symbol', 'function', 'number'];
|
||||
|
||||
if (inspectTypes.includes(typeof val)) {
|
||||
return inspect(val, inspectOptions);
|
||||
} else {
|
||||
return String(val);
|
||||
}
|
||||
}
|
||||
|
||||
function formatWithOptions(inspectOptions, ...args) {
|
||||
const first = args[0];
|
||||
const parts = [];
|
||||
let a = 0;
|
||||
let str = '';
|
||||
let join = '';
|
||||
|
||||
const firstIsString = typeof first === 'string';
|
||||
|
||||
if (firstIsString && args.length === 1) {
|
||||
return first;
|
||||
}
|
||||
|
||||
if (firstIsString && /%[sjdOoif%]/.test(first)) {
|
||||
let i, tempStr;
|
||||
let str = '';
|
||||
let a = 1;
|
||||
if (typeof first === 'string') {
|
||||
if (args.length === 1) {
|
||||
return first;
|
||||
}
|
||||
let tempStr;
|
||||
let lastPos = 0;
|
||||
|
||||
for (i = 0; i < first.length - 1; i++) {
|
||||
for (var i = 0; i < first.length - 1; i++) {
|
||||
if (first.charCodeAt(i) === 37) { // '%'
|
||||
const nextChar = first.charCodeAt(++i);
|
||||
if (a !== args.length) {
|
||||
if (a + 1 !== args.length) {
|
||||
switch (nextChar) {
|
||||
case 115: // 's'
|
||||
tempStr = String(args[a++]);
|
||||
tempStr = String(args[++a]);
|
||||
break;
|
||||
case 106: // 'j'
|
||||
tempStr = tryStringify(args[a++]);
|
||||
tempStr = tryStringify(args[++a]);
|
||||
break;
|
||||
case 100: // 'd'
|
||||
const tempNum = args[a++];
|
||||
const tempNum = args[++a];
|
||||
// eslint-disable-next-line valid-typeof
|
||||
if (typeof tempNum === 'bigint') {
|
||||
tempStr = `${tempNum}n`;
|
||||
@ -127,20 +114,20 @@ function formatWithOptions(inspectOptions, ...args) {
|
||||
}
|
||||
break;
|
||||
case 79: // 'O'
|
||||
tempStr = inspect(args[a++], inspectOptions);
|
||||
tempStr = inspect(args[++a], inspectOptions);
|
||||
break;
|
||||
case 111: // 'o'
|
||||
{
|
||||
const opts = Object.assign({}, inspectOptions, {
|
||||
tempStr = inspect(args[++a], {
|
||||
...inspectOptions,
|
||||
showHidden: true,
|
||||
showProxy: true,
|
||||
depth: 4
|
||||
});
|
||||
tempStr = inspect(args[a++], opts);
|
||||
break;
|
||||
}
|
||||
case 105: // 'i'
|
||||
const tempInteger = args[a++];
|
||||
const tempInteger = args[++a];
|
||||
// eslint-disable-next-line valid-typeof
|
||||
if (typeof tempInteger === 'bigint') {
|
||||
tempStr = `${tempInteger}n`;
|
||||
@ -151,7 +138,7 @@ function formatWithOptions(inspectOptions, ...args) {
|
||||
}
|
||||
break;
|
||||
case 102: // 'f'
|
||||
const tempFloat = args[a++];
|
||||
const tempFloat = args[++a];
|
||||
if (typeof tempFloat === 'symbol') {
|
||||
tempStr = 'NaN';
|
||||
} else {
|
||||
@ -176,24 +163,32 @@ function formatWithOptions(inspectOptions, ...args) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lastPos === 0) {
|
||||
str = first;
|
||||
} else if (lastPos < first.length) {
|
||||
str += first.slice(lastPos);
|
||||
}
|
||||
|
||||
parts.push(str);
|
||||
while (a < args.length) {
|
||||
parts.push(formatValue(args[a], inspectOptions));
|
||||
if (lastPos !== 0) {
|
||||
a++;
|
||||
}
|
||||
} else {
|
||||
for (const arg of args) {
|
||||
parts.push(formatValue(arg, inspectOptions));
|
||||
join = ' ';
|
||||
if (lastPos < first.length) {
|
||||
str += first.slice(lastPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parts.join(' ');
|
||||
while (a < args.length) {
|
||||
const value = args[a];
|
||||
// TODO(BridgeAR): This should apply for all besides strings. Especially
|
||||
// BigInt should be properly inspected.
|
||||
str += join;
|
||||
if (typeof value !== 'string' &&
|
||||
typeof value !== 'boolean' &&
|
||||
// eslint-disable-next-line valid-typeof
|
||||
typeof value !== 'bigint') {
|
||||
str += inspect(value, inspectOptions);
|
||||
} else {
|
||||
str += value;
|
||||
}
|
||||
join = ' ';
|
||||
a++;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
const debugs = {};
|
||||
|
Loading…
x
Reference in New Issue
Block a user