From 9532dd85bc26a9e454422a79edf9ca4f9904cb9b Mon Sep 17 00:00:00 2001 From: Evan Lucas Date: Mon, 22 Feb 2016 02:55:55 -0600 Subject: [PATCH] util: improve util.format performance By manually copying arguments and breaking the try/catch out, we are able to improve the performance of util.format by 20-100% (depending on the types). PR-URL: https://github.com/nodejs/node/pull/5360 Reviewed-By: James M Snell --- lib/util.js | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/util.js b/lib/util.js index c370d9509e1ca3..f56d812eee26f3 100644 --- a/lib/util.js +++ b/lib/util.js @@ -9,39 +9,48 @@ const isError = internalUtil.isError; var Debug; +function tryStringify(arg) { + try { + return JSON.stringify(arg); + } catch (_) { + return '[Circular]'; + } +} + const formatRegExp = /%[sdj%]/g; exports.format = function(f) { if (typeof f !== 'string') { - var objects = []; + const objects = new Array(arguments.length); for (var index = 0; index < arguments.length; index++) { - objects.push(inspect(arguments[index])); + objects[index] = inspect(arguments[index]); } return objects.join(' '); } if (arguments.length === 1) return f; - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function(x) { + 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': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; - } + case '%j': return tryStringify(args[i++]); // falls through default: return x; } }); - for (var x = args[i]; i < len; x = args[++i]) { + while (i < len) { + const x = args[i++]; if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { str += ' ' + x; } else {