Skip to content

Commit

Permalink
perf: improve equality detection and reuse it
Browse files Browse the repository at this point in the history
  • Loading branch information
anonrig committed Sep 10, 2022
1 parent 6bf2636 commit 5707bcb
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 14 deletions.
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ console.log(qs.stringify({ foo: ['bar', 'baz'] }))
╔═════════════════════════════════════════╤═════════╤═══════════════════╤═══════════╗
║ Slower tests │ Samples │ Result │ Tolerance ║
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
║ qs │ 10000 │ 302595.31 op/sec │ ± 1.22 % ║
║ query-string │ 9500334820.82 op/sec │ ± 0.99 % ║
║ querystringify │ 1000 437899.50 op/sec │ ± 0.73 % ║
║ @aws-sdk/querystring-parser │ 1000 │ 454836.96 op/sec │ ± 0.69 % ║
║ URLSearchParams-with-Object.fromEntries │ 1500 849572.92 op/sec │ ± 0.89 % ║
║ URLSearchParams-with-construct │ 10000 │ 1190835.28 op/sec │ ± 3.22 % ║
║ node:querystring │ 10000 │ 1384717.43 op/sec │ ± 2.99 % ║
║ querystringparser │ 35001735544.65 op/sec │ ± 0.95 % ║
║ qs │ 10000 │ 310825.09 op/sec │ ± 1.29 % ║
║ query-string │ 1000340059.83 op/sec │ ± 0.82 % ║
║ querystringify │ 10000 435456.34 op/sec │ ± 1.06 % ║
║ @aws-sdk/querystring-parser │ 1000 │ 451618.35 op/sec │ ± 0.85 % ║
║ URLSearchParams-with-Object.fromEntries │ 10000 876030.86 op/sec │ ± 1.78 % ║
║ URLSearchParams-with-construct │ 10000 │ 1239366.24 op/sec │ ± 2.59 % ║
║ node:querystring │ 10000 │ 1442731.43 op/sec │ ± 2.95 % ║
║ querystringparser │ 30001863385.29 op/sec │ ± 0.99 % ║
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
║ Fastest test │ Samples │ Result │ Tolerance ║
╟─────────────────────────────────────────┼─────────┼───────────────────┼───────────╢
║ fast-querystring │ 10000 │ 2023187.35 op/sec │ ± 2.67 % ║
║ fast-querystring │ 10000 │ 2086260.18 op/sec │ ± 3.18 % ║
╚═════════════════════════════════════════╧═════════╧═══════════════════╧═══════════╝
```

Expand Down
15 changes: 10 additions & 5 deletions lib/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,22 @@ function parse(input) {
let keyHasPlus = false;
let valueHasPlus = false;
let hasBothKeyValuePair = false;
let keyEndingIndex = 0;
let c = 0;

// Have a boundary of input.length + 1 to access last pair inside the loop.
for (let i = 0; i < inputLength + 1; i++) {
let c = i !== inputLength ? input.charCodeAt(i) : -1;
c = i !== inputLength ? input.charCodeAt(i) : 38;

// Handle '&' and end of line to pass the current values to result
if (c === 38 || c === -1) {
if (c === 38) {
hasBothKeyValuePair = equalityIndex > startingIndex;
keyEndingIndex = hasBothKeyValuePair ? equalityIndex : i;
key = input.slice(startingIndex + 1, keyEndingIndex);

// Optimization: Reuse equality index to store the end of key
if (!hasBothKeyValuePair) {
equalityIndex = i;
}

key = input.slice(startingIndex + 1, equalityIndex);

// Add key/value pair only if the range size is greater than 1; a.k.a. contains at least "="
if (hasBothKeyValuePair || key.length > 0) {
Expand Down

0 comments on commit 5707bcb

Please sign in to comment.