From a7dfb98e4b0aa36c645c157974d2f8d661031c16 Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 6 Mar 2025 09:42:51 +0000 Subject: [PATCH 1/2] String accumulation is faster than array join --- index.js | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/index.js b/index.js index aa93257..bc168ff 100644 --- a/index.js +++ b/index.js @@ -20,6 +20,14 @@ const NULL_STRING = 'NULL' function makeParseArrayWithTransform (transform) { const haveTransform = transform != null return function parseArray (str) { + const rbraceIndex = str.length - 1 + if (rbraceIndex === 1) { + return [] + } + if (str[rbraceIndex] !== RBRACE) { + throw new Error('Invalid array text - must end with }') + } + // If starts with `[`, it is specifying the index boundas. Skip past first `=`. let position = 0 if (str[position] === LBRACKET) { @@ -29,17 +37,12 @@ function makeParseArrayWithTransform (transform) { if (str[position++] !== LBRACE) { throw new Error('Invalid array text - must start with {') } - const rbraceIndex = str.length - 1 - if (str[rbraceIndex] !== RBRACE) { - throw new Error('Invalid array text - must end with }') - } const output = [] let current = output const stack = [] let currentStringStart = position - const currentStringParts = [] - let hasStringParts = false + let currentString = null let expectValue = true for (; position < rbraceIndex; ++position) { @@ -56,8 +59,11 @@ function makeParseArrayWithTransform (transform) { while (backSlash !== -1 && backSlash < dquot) { position = backSlash const part = str.slice(currentStringStart, position) - currentStringParts.push(part) - hasStringParts = true + if (currentString === null) { + currentString = part + } else { + currentString += part + } currentStringStart = ++position if (dquot === position++) { // This was an escaped doublequote; find the next one! @@ -68,13 +74,12 @@ function makeParseArrayWithTransform (transform) { } position = dquot const part = str.slice(currentStringStart, position) - if (hasStringParts) { - const final = currentStringParts.join('') + part - current.push(haveTransform ? transform(final) : final) - currentStringParts.length = 0 - hasStringParts = false - } else { + if (currentString === null) { current.push(haveTransform ? transform(part) : part) + } else { + currentString += part + current.push(haveTransform ? transform(currentString) : currentString) + currentString = null } expectValue = false } else if (char === LBRACE) { From 0f5cca5b4117869487eb3176df63a626107346ef Mon Sep 17 00:00:00 2001 From: Benjie Gillam Date: Thu, 6 Mar 2025 10:03:05 +0000 Subject: [PATCH 2/2] No measurable performance difference and simpler code --- index.js | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index bc168ff..3383d2b 100644 --- a/index.js +++ b/index.js @@ -42,7 +42,7 @@ function makeParseArrayWithTransform (transform) { const stack = [] let currentStringStart = position - let currentString = null + let currentString = '' let expectValue = true for (; position < rbraceIndex; ++position) { @@ -59,11 +59,7 @@ function makeParseArrayWithTransform (transform) { while (backSlash !== -1 && backSlash < dquot) { position = backSlash const part = str.slice(currentStringStart, position) - if (currentString === null) { - currentString = part - } else { - currentString += part - } + currentString += part currentStringStart = ++position if (dquot === position++) { // This was an escaped doublequote; find the next one! @@ -74,13 +70,9 @@ function makeParseArrayWithTransform (transform) { } position = dquot const part = str.slice(currentStringStart, position) - if (currentString === null) { - current.push(haveTransform ? transform(part) : part) - } else { - currentString += part - current.push(haveTransform ? transform(currentString) : currentString) - currentString = null - } + currentString += part + current.push(haveTransform ? transform(currentString) : currentString) + currentString = '' expectValue = false } else if (char === LBRACE) { const newArray = []