Skip to content

Commit

Permalink
perf: separate no-comment minifier for better performance
Browse files Browse the repository at this point in the history
  • Loading branch information
aminya committed Sep 10, 2024
1 parent 961c7d7 commit 034b4e5
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 8 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"format.d": "dub run --build=release --quiet dfmt -- --soft_max_line_length 110 --indent_size 2 --inplace ./src ./benchmark",
"lint": "eslint . --fix",
"prepublishOnly": "shx rm -rf ./dist/tsconfig.tsbuildinfo ./dist/*.zip ./dist/build.* && chmod +x ./dist/*/minijson",
"start.benchmark.js": "node ./benchmark/js-benchmark.mjs",
"start.benchmark.node": "node ./benchmark/native-benchmark.mjs",
"start.browser": "servor ./dist/ --browse --reload",
"start.node": "node ./dist/node/cli.js",
Expand Down
67 changes: 59 additions & 8 deletions src/native/lib.d
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,60 @@ const tokenizerNoComment = ctRegex!(`[\n\r"[]]`, "g");
the minified json string
*/
string minifyString(in string jsonString, in bool hasComment = false) @trusted
{
return hasComment ? minifyStringWithComments(jsonString) : minifyStringNoComments(jsonString);
}

string minifyStringNoComments(in string jsonString) @trusted
{
auto in_string = false;
string result;
size_t from = 0;
auto rightContext = "";

auto match = jsonString.matchAll(tokenizerNoComment);

while (!match.empty())
{
const matchFrontHit = match.front().hit();

rightContext = match.post();

// update from for the next iteration
const prevFrom = from;
from = jsonString.length - rightContext.length; // lastIndex

auto leftContextSubstr = match.pre()[prevFrom .. $];
const noLeftContext = leftContextSubstr.length == 0;
if (!noLeftContext)
{
if (!in_string)
{
leftContextSubstr = remove_spaces(leftContextSubstr);
}
result ~= leftContextSubstr;
}
if (matchFrontHit == "\"")
{
if (!in_string || noLeftContext || hasNoSlashOrEvenNumberOfSlashes(leftContextSubstr))
{
// start of string with ", or unescaped " character found to end string
in_string = !in_string;
}
--from; // include " character in next catch
rightContext = jsonString[from .. $];
}
else if (notSlashAndNoSpaceOrBreak(matchFrontHit))
{
result ~= matchFrontHit;
}
match.popFront();
}
result ~= rightContext;
return result;
}

string minifyStringWithComments(in string jsonString) @trusted
{
auto in_string = false;
auto in_multiline_comment = false;
Expand All @@ -26,9 +80,7 @@ string minifyString(in string jsonString, in bool hasComment = false) @trusted
size_t from = 0;
auto rightContext = "";

const tokenizer = !hasComment ? tokenizerNoComment : tokenizerWithComment;

auto match = jsonString.matchAll(tokenizer);
auto match = jsonString.matchAll(tokenizerWithComment);

while (!match.empty())
{
Expand All @@ -40,10 +92,9 @@ string minifyString(in string jsonString, in bool hasComment = false) @trusted
const prevFrom = from;
from = jsonString.length - rightContext.length; // lastIndex

const notInComment = (!in_multiline_comment && !in_singleline_comment);
const noCommentOrNotInComment = !hasComment || notInComment;
const notInComment = !in_multiline_comment && !in_singleline_comment;

if (noCommentOrNotInComment)
if (notInComment)
{
auto leftContextSubstr = match.pre()[prevFrom .. $];
const noLeftContext = leftContextSubstr.length == 0;
Expand All @@ -67,7 +118,7 @@ string minifyString(in string jsonString, in bool hasComment = false) @trusted
}
}
// comments
if (hasComment && !in_string)
if (!in_string)
{
if (notInComment)
{
Expand All @@ -93,7 +144,7 @@ string minifyString(in string jsonString, in bool hasComment = false) @trusted
in_singleline_comment = false;
}
}
else if (!hasComment && notSlashAndNoSpaceOrBreak(matchFrontHit))
else if (notSlashAndNoSpaceOrBreak(matchFrontHit))
{
result ~= matchFrontHit;
}
Expand Down

0 comments on commit 034b4e5

Please sign in to comment.