diff --git a/benchmark/util/format.js b/benchmark/util/format.js index 00b59519dfd39a..6f171318ee28bf 100644 --- a/benchmark/util/format.js +++ b/benchmark/util/format.js @@ -2,35 +2,30 @@ const util = require('util'); const common = require('../common'); -const types = [ - 'string', - 'number', - 'object', - 'unknown', - 'no-replace' -]; -const bench = common.createBenchmark(main, { - n: [2e6], - type: types -}); const inputs = { - 'string': ['Hello, my name is %s', 'fred'], - 'number': ['Hi, I was born in %d', 1942], - 'object': ['An error occurred %j', { msg: 'This is an error', code: 'ERR' }], + 'string': ['Hello, my name is %s', 'Fred'], + 'string-2': ['Hello, %s is my name', 'Fred'], + 'number': ['Hi, I was born in %d', 1989], + 'replace-object': ['An error occurred %j', { msg: 'This is an error' }], 'unknown': ['hello %a', 'test'], - 'no-replace': [1, 2] + 'no-replace': [1, 2], + 'no-replace-2': ['foobar', 'yeah', 'mensch', 5], + 'only-objects': [{ msg: 'This is an error' }, { msg: 'This is an error' }], + 'many-%': ['replace%%%%s%%%%many%s%s%s', 'percent'], }; -function main(conf) { - const n = conf.n | 0; - const type = conf.type; +const bench = common.createBenchmark(main, { + n: [4e6], + type: Object.keys(inputs) +}); - const input = inputs[type]; +function main({ n, type }) { + const [first, second] = inputs[type]; bench.start(); for (var i = 0; i < n; i++) { - util.format(input[0], input[1]); + util.format(first, second); } bench.end(n); } diff --git a/lib/util.js b/lib/util.js index cbd8f0cfcd156d..c12d80de34086b 100644 --- a/lib/util.js +++ b/lib/util.js @@ -177,12 +177,16 @@ function tryStringify(arg) { } function format(f) { + var i, tempStr; if (typeof f !== 'string') { - const objects = new Array(arguments.length); - for (var index = 0; index < arguments.length; index++) { - objects[index] = inspect(arguments[index]); + if (arguments.length === 0) return ''; + var res = ''; + for (i = 0; i < arguments.length - 1; i++) { + res += inspect(arguments[i]); + res += ' '; } - return objects.join(' '); + res += inspect(arguments[i]); + return res; } if (arguments.length === 1) return f; @@ -190,49 +194,49 @@ function format(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) { - if (f.charCodeAt(i + 1) !== 37/*'%'*/ && a >= arguments.length) { - ++i; - continue; - } - if (lastPos < i) + for (i = 0; i < f.length - 1; i++) { + if (f.charCodeAt(i) === 37) { // '%' + const nextChar = f.charCodeAt(++i); + if (a !== arguments.length) { + switch (nextChar) { + case 115: // 's' + tempStr = String(arguments[a++]); + break; + case 106: // 'j' + tempStr = tryStringify(arguments[a++]); + break; + case 100: // 'd' + tempStr = `${Number(arguments[a++])}`; + break; + case 79: // 'O' + tempStr = inspect(arguments[a++]); + break; + case 111: // 'o' + tempStr = inspect(arguments[a++], + { showHidden: true, depth: 4, showProxy: true }); + break; + case 105: // 'i' + tempStr = `${parseInt(arguments[a++])}`; + break; + case 102: // 'f' + tempStr = `${parseFloat(arguments[a++])}`; + break; + case 37: // '%' + str += f.slice(lastPos, i); + lastPos = i + 1; + continue; + default: // any other character is not a correct placeholder + continue; + } + if (lastPos !== i - 1) + str += f.slice(lastPos, i - 1); + str += tempStr; + lastPos = i + 1; + } else if (nextChar === 37) { str += f.slice(lastPos, i); - switch (f.charCodeAt(i + 1)) { - case 100: // 'd' - str += Number(arguments[a++]); - break; - case 105: // 'i' - str += parseInt(arguments[a++]); - break; - case 102: // 'f' - str += parseFloat(arguments[a++]); - break; - case 106: // 'j' - str += tryStringify(arguments[a++]); - break; - case 115: // 's' - str += String(arguments[a++]); - break; - case 79: // 'O' - str += inspect(arguments[a++]); - break; - case 111: // 'o' - str += inspect(arguments[a++], - { showHidden: true, depth: 4, showProxy: true }); - break; - case 37: // '%' - str += '%'; - break; - default: // any other character is not a correct placeholder - str += '%'; - lastPos = i = i + 1; - continue; + lastPos = i + 1; } - lastPos = i = i + 2; - continue; } - ++i; } if (lastPos === 0) str = f; @@ -240,7 +244,7 @@ function format(f) { str += f.slice(lastPos); while (a < arguments.length) { const x = arguments[a++]; - if (x === null || (typeof x !== 'object' && typeof x !== 'symbol')) { + if ((typeof x !== 'object' && typeof x !== 'symbol') || x === null) { str += ` ${x}`; } else { str += ` ${inspect(x)}`;