From 4ff320111cba0feb98a2d17d5ef0b5cd4edd0722 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Thu, 1 Dec 2022 19:21:39 +0100 Subject: [PATCH 1/3] v8: changed ArrayPrototypeJoin with custom join implementation --- lib/internal/per_context/primordials.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index 370f5953dc78e5..12642c9714f798 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -710,5 +710,22 @@ primordials.SafeStringPrototypeSearch = (str, regexp) => { return match ? match.index : -1; }; +// The built-in Array#join is slower in v8 6.0 +function join(output, separator) { + let str = ''; + if (output.length !== 0) { + const lastIndex = output.length - 1; + for (let i = 0; i < lastIndex; i++) { + // It is faster not to use a template string here + str += output[i]; + str += separator; + } + str += output[lastIndex]; + } + return str; +} + +primordials.ArrayPrototypeJoin = join; + ObjectSetPrototypeOf(primordials, null); ObjectFreeze(primordials); From 99cb6db6c8959c812b9cf6413a00370d29ca3233 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Thu, 1 Dec 2022 19:49:15 +0100 Subject: [PATCH 2/3] fix: removed join from internal/util and updated join default value --- lib/internal/per_context/primordials.js | 2 +- lib/internal/util.js | 16 ---------------- lib/internal/util/inspect.js | 9 ++++----- 3 files changed, 5 insertions(+), 22 deletions(-) diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index 12642c9714f798..9c7d99e2dfa5f7 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -711,7 +711,7 @@ primordials.SafeStringPrototypeSearch = (str, regexp) => { }; // The built-in Array#join is slower in v8 6.0 -function join(output, separator) { +function join(output, separator = ',') { let str = ''; if (output.length !== 0) { const lastIndex = output.length - 1; diff --git a/lib/internal/util.js b/lib/internal/util.js index 7825172e66e2e1..02f74383383229 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -387,21 +387,6 @@ function promisify(original) { promisify.custom = kCustomPromisifiedSymbol; -// The built-in Array#join is slower in v8 6.0 -function join(output, separator) { - let str = ''; - if (output.length !== 0) { - const lastIndex = output.length - 1; - for (let i = 0; i < lastIndex; i++) { - // It is faster not to use a template string here - str += output[i]; - str += separator; - } - str += output[lastIndex]; - } - return str; -} - // As of V8 6.6, depending on the size of the array, this is anywhere // between 1.5-10x faster than the two-arg version of Array#splice() function spliceOne(list, index) { @@ -590,7 +575,6 @@ module.exports = { isArrayBufferDetached, isError, isInsideNodeModules, - join, lazyDOMException, lazyDOMExceptionClass, normalizeEncoding, diff --git a/lib/internal/util/inspect.js b/lib/internal/util/inspect.js index abbb0d9c8ebc86..f53e1797057d7b 100644 --- a/lib/internal/util/inspect.js +++ b/lib/internal/util/inspect.js @@ -114,7 +114,6 @@ const { const { customInspectSymbol, isError, - join, removeColors } = require('internal/util'); @@ -2057,7 +2056,7 @@ function reduceToSingleString( const start = output.length + ctx.indentationLvl + braces[0].length + base.length + 10; if (isBelowBreakLength(ctx, output, start, base)) { - const joinedOutput = join(output, ', '); + const joinedOutput = ArrayPrototypeJoin(output, ', '); if (!StringPrototypeIncludes(joinedOutput, '\n')) { return `${base ? `${base} ` : ''}${braces[0]} ${joinedOutput}` + ` ${braces[1]}`; @@ -2068,12 +2067,12 @@ function reduceToSingleString( // Line up each entry on an individual line. const indentation = `\n${StringPrototypeRepeat(' ', ctx.indentationLvl)}`; return `${base ? `${base} ` : ''}${braces[0]}${indentation} ` + - `${join(output, `,${indentation} `)}${indentation}${braces[1]}`; + `${ArrayPrototypeJoin(output, `,${indentation} `)}${indentation}${braces[1]}`; } // Line up all entries on a single line in case the entries do not exceed // `breakLength`. if (isBelowBreakLength(ctx, output, 0, base)) { - return `${braces[0]}${base ? ` ${base}` : ''} ${join(output, ', ')} ` + + return `${braces[0]}${base ? ` ${base}` : ''} ${ArrayPrototypeJoin(output, ', ')} ` + braces[1]; } const indentation = StringPrototypeRepeat(' ', ctx.indentationLvl); @@ -2083,7 +2082,7 @@ function reduceToSingleString( const ln = base === '' && braces[0].length === 1 ? ' ' : `${base ? ` ${base}` : ''}\n${indentation} `; // Line up each entry on an individual line. - return `${braces[0]}${ln}${join(output, `,\n${indentation} `)} ${braces[1]}`; + return `${braces[0]}${ln}${ArrayPrototypeJoin(output, `,\n${indentation} `)} ${braces[1]}`; } function hasBuiltInToString(value) { From 6e15596c7d7e48c412af41af9724be8c4ca53378 Mon Sep 17 00:00:00 2001 From: Marco Ippolito Date: Fri, 2 Dec 2022 09:37:08 +0100 Subject: [PATCH 3/3] fix: in case element is undefined use '' as per specification --- lib/internal/per_context/primordials.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index 9c7d99e2dfa5f7..a639f4db2f7573 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -717,10 +717,10 @@ function join(output, separator = ',') { const lastIndex = output.length - 1; for (let i = 0; i < lastIndex; i++) { // It is faster not to use a template string here - str += output[i]; + str += output[i] ?? ''; str += separator; } - str += output[lastIndex]; + str += output[lastIndex] ?? ''; } return str; }