Skip to content

Commit

Permalink
util: improve format() performance further
Browse files Browse the repository at this point in the history
Replacing the regexp and replace function with a loop improves
performance by ~60-200%.

PR-URL: #5360
Reviewed-By: James M Snell <jasnell@gmail.com>
  • Loading branch information
mscdex authored and evanlucas committed Mar 4, 2016
1 parent 8d72b0d commit c490b8b
Showing 1 changed file with 49 additions and 24 deletions.
73 changes: 49 additions & 24 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ function tryStringify(arg) {
}
}

const formatRegExp = /%[sdj%]/g;
exports.format = function(f) {
if (typeof f !== 'string') {
const objects = new Array(arguments.length);
Expand All @@ -27,30 +26,56 @@ exports.format = function(f) {
return objects.join(' ');
}

if (arguments.length === 1) return f;

const len = arguments.length;
const args = new Array(len);
var i;
for (i = 0; i < len; i++) {
args[i] = arguments[i];
}

i = 1;
var str = f.replace(formatRegExp, function(x) {
if (x === '%%') return '%';
if (i >= len) return x;
switch (x) {
case '%s': return String(args[i++]);
case '%d': return Number(args[i++]);
case '%j': return tryStringify(args[i++]);
// falls through
default:
return x;
var argLen = arguments.length;

if (argLen === 1) return f;

var str = '';
var a = 1;
var lastPos = 0;
for (var i = 0; i < f.length;) {
if (f.charCodeAt(i) === 37/*'%'*/ && i + 1 < f.length) {
switch (f.charCodeAt(i + 1)) {
case 100: // 'd'
if (a >= argLen)
break;
if (lastPos < i)
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) {
const x = args[i++];
++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')) {
str += ' ' + x;
} else {
Expand Down

0 comments on commit c490b8b

Please sign in to comment.