util: improve format() performance further
Replacing the regexp and replace function with a loop improves performance by ~60-200%. PR-URL: https://github.com/nodejs/node/pull/5360 Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
8d72b0d291
commit
c490b8ba54
69
lib/util.js
69
lib/util.js
@ -17,7 +17,6 @@ function tryStringify(arg) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatRegExp = /%[sdj%]/g;
|
|
||||||
exports.format = function(f) {
|
exports.format = function(f) {
|
||||||
if (typeof f !== 'string') {
|
if (typeof f !== 'string') {
|
||||||
const objects = new Array(arguments.length);
|
const objects = new Array(arguments.length);
|
||||||
@ -27,30 +26,56 @@ exports.format = function(f) {
|
|||||||
return objects.join(' ');
|
return objects.join(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments.length === 1) return f;
|
var argLen = arguments.length;
|
||||||
|
|
||||||
const len = arguments.length;
|
if (argLen === 1) return f;
|
||||||
const args = new Array(len);
|
|
||||||
var i;
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
args[i] = arguments[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 1;
|
var str = '';
|
||||||
var str = f.replace(formatRegExp, function(x) {
|
var a = 1;
|
||||||
if (x === '%%') return '%';
|
var lastPos = 0;
|
||||||
if (i >= len) return x;
|
for (var i = 0; i < f.length;) {
|
||||||
switch (x) {
|
if (f.charCodeAt(i) === 37/*'%'*/ && i + 1 < f.length) {
|
||||||
case '%s': return String(args[i++]);
|
switch (f.charCodeAt(i + 1)) {
|
||||||
case '%d': return Number(args[i++]);
|
case 100: // 'd'
|
||||||
case '%j': return tryStringify(args[i++]);
|
if (a >= argLen)
|
||||||
// falls through
|
break;
|
||||||
default:
|
if (lastPos < i)
|
||||||
return x;
|
str += f.slice(lastPos, i);
|
||||||
|
str += Number(arguments[a++]);
|
||||||
|
lastPos = i = i + 2;
|
||||||
|
continue;
|
||||||
|
case 106: // 'j'
|
||||||
|
if (a >= argLen)
|
||||||
|
break;
|
||||||
|
if (lastPos < i)
|
||||||
|
str += f.slice(lastPos, i);
|
||||||
|
str += tryStringify(arguments[a++]);
|
||||||
|
lastPos = i = i + 2;
|
||||||
|
continue;
|
||||||
|
case 115: // 's'
|
||||||
|
if (a >= argLen)
|
||||||
|
break;
|
||||||
|
if (lastPos < i)
|
||||||
|
str += f.slice(lastPos, i);
|
||||||
|
str += String(arguments[a++]);
|
||||||
|
lastPos = i = i + 2;
|
||||||
|
continue;
|
||||||
|
case 37: // '%'
|
||||||
|
if (lastPos < i)
|
||||||
|
str += f.slice(lastPos, i);
|
||||||
|
str += '%';
|
||||||
|
lastPos = i = i + 2;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
while (i < len) {
|
++i;
|
||||||
const x = args[i++];
|
}
|
||||||
|
if (lastPos === 0)
|
||||||
|
str = f;
|
||||||
|
else if (lastPos < f.length)
|
||||||
|
str += f.slice(lastPos);
|
||||||
|
while (a < argLen) {
|
||||||
|
const x = arguments[a++];
|
||||||
if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) {
|
if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) {
|
||||||
str += ' ' + x;
|
str += ' ' + x;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user