From b3feb523a4964f6aa1544f154fafd3c097cfcfcc Mon Sep 17 00:00:00 2001 From: Aras Abbasi Date: Fri, 29 Sep 2023 13:04:38 +0200 Subject: [PATCH] errors: improve formatList in errors.js PR-URL: https://github.com/nodejs/node/pull/49642 Reviewed-By: Yagiz Nizipli Reviewed-By: LiviaMedeiros Reviewed-By: Antoine du Hamel --- benchmark/error/format-list.js | 44 +++++++++++++++++++++++++ lib/internal/errors.js | 10 ++++-- test/parallel/test-error-format-list.js | 2 +- 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 benchmark/error/format-list.js diff --git a/benchmark/error/format-list.js b/benchmark/error/format-list.js new file mode 100644 index 00000000000000..f35ca3593a743c --- /dev/null +++ b/benchmark/error/format-list.js @@ -0,0 +1,44 @@ +'use strict'; + +const common = require('../common.js'); + +const bench = common.createBenchmark(main, { + n: [1e7], + input: [ + '', + 'a', + 'a,b', + 'a,b,c', + 'a,b,c,d', + ], + type: [ + 'undefined', + 'and', + 'or', + ], +}, { + flags: ['--expose-internals'], +}); + +function main({ n, input, type }) { + const { + formatList, + } = require('internal/errors'); + + const list = input.split(','); + + if (type === 'undefined') { + bench.start(); + for (let i = 0; i < n; ++i) { + formatList(list); + } + bench.end(n); + return; + } + + bench.start(); + for (let i = 0; i < n; ++i) { + formatList(list, type); + } + bench.end(n); +} diff --git a/lib/internal/errors.js b/lib/internal/errors.js index 6bba8ec095e86e..4928ac97d51537 100644 --- a/lib/internal/errors.js +++ b/lib/internal/errors.js @@ -967,8 +967,14 @@ function determineSpecificType(value) { * @returns {string} */ function formatList(array, type = 'and') { - return array.length < 3 ? ArrayPrototypeJoin(array, ` ${type} `) : - `${ArrayPrototypeJoin(ArrayPrototypeSlice(array, 0, -1), ', ')}, ${type} ${array[array.length - 1]}`; + switch (array.length) { + case 0: return ''; + case 1: return `${array[0]}`; + case 2: return `${array[0]} ${type} ${array[1]}`; + case 3: return `${array[0]}, ${array[1]}, ${type} ${array[2]}`; + default: + return `${ArrayPrototypeJoin(ArrayPrototypeSlice(array, 0, -1), ', ')}, ${type} ${array[array.length - 1]}`; + } } module.exports = { diff --git a/test/parallel/test-error-format-list.js b/test/parallel/test-error-format-list.js index 54ae4e0aee714d..2fd95584d22318 100644 --- a/test/parallel/test-error-format-list.js +++ b/test/parallel/test-error-format-list.js @@ -11,7 +11,7 @@ if (!common.hasIntl) common.skip('missing Intl'); const and = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' }); const or = new Intl.ListFormat('en', { style: 'long', type: 'disjunction' }); - const input = ['apple', 'banana', 'orange']; + const input = ['apple', 'banana', 'orange', 'pear']; for (let i = 0; i < input.length; i++) { const slicedInput = input.slice(0, i); strictEqual(formatList(slicedInput), and.format(slicedInput));